长上下文:能力与挑战并存 当模型支持百万token的上下文时,新的问题随之而来:模型真的能有效利用这么长的上下文吗?研究表明,上下文长度和上下文利用效率是两个截然不同的问题。
长上下文的技术难点 注意力衰减 模型对上下文中不同位置信息的关注程度不均匀:
def measure_attention_decay(model, context_length, key_position): """测量模型对不同位置信息的关注度""" # 在上下文的不同位置放置关键信息 results = [] for pos in [0, 0.1, 0.25, 0.5, 0.75, 0.9, 1.0]: # pos=0表示开头,pos=1表示结尾 context = build_context_with_key_at(pos, context_length) question = "根据上下文中的关键信息回答..." accuracy = test_answer_accuracy(model, context, question) results.append({"position": pos, "accuracy": accuracy}) return results # 典型结果: # position=0.0: accuracy=85% # position=0.25: accuracy=52% ← 中间区域下降 # position=0.5: accuracy=48% ← 最低点 # position=0.75: accuracy=55% # position=1.0: accuracy=82% Needle-in-a-Haystack测试 这是评估长上下文能力的标准测试:在大量无关文本中隐藏一句关键信息,测试模型能否找到:
def needle_in_haystack(model, context_length, needle_position): """大海捞针测试""" # 生成填充文本 filler = generate_filler_text(context_length - 200) # 关键信息(针) needle = "密码是:Sk7-9mPq" # 在指定位置插入针 insert_pos = int(len(filler) * needle_position) context = filler[:insert_pos] + needle + filler[insert_pos:] # 测试模型能否找到 question = "文档中提到的密码是什么?" response = model.generate(context + "\n\n" + question) return { "found": "Sk7-9mPq" in response, "context_length": context_length, "needle_position": needle_position } def full_evaluation(model): """全面评估""" results = [] for length in [1000, 5000, 10000, 50000, 100000, 500000]: for pos in [0, 0.1, 0.3, 0.5, 0.7, 0.9, 1.0]: result = needle_in_haystack(model, length, pos) results.append(result) # 生成热力图 return plot_heatmap(results, x="position", y="length", color="found") 多针测试 更复杂的测试在上下文中放置多个关键信息:
...