长度上限意味着什么
多数 embedding 模型有固定的输入长度上限(常见 512 token 这一档,长文本模型可到 8k 以上),超出部分会被静默截断。长文档要么截断(尾部内容彻底检索不到),要么分块编码后把多个向量池化成一个(如平均池化)。两种做法都会改变向量语义,必须先在自有评测集上对比,再决定用哪种。
基本信息
| 上限来源 | 模型训练时的 max_seq_length,需查模型卡的明确数值 |
|---|---|
| 截断方向 | 多数实现从左往右保留头部,尾部直接丢弃 |
| 池化方式 | 平均、加权平均、取首块向量等,需再归一化 |
| 核对时机 | 切分参数调整后要重新核对块长度分布 |
典型使用场景
- 合同与法规入库:条款分布均匀,评估池化是否比截断更稳
- 技术手册:正文长且信息密度高,通常更适合分块后逐块入库
- 短文本场景:工单与评论远低于上限,不存在该问题但要确认前缀占用
- 模型迁移:换模型后上限变化,原有切分长度需要重新核对
- 成本优化:块越短向量调用次数越多,需要在语义完整与调用次数间取舍
分块平均池化
分块平均池化
import numpy as np
# 先按模型上限把长文档切成多块,再逐块编码
vecs = model.encode(chunks_of_doc, normalize_embeddings=True)
doc_vec = vecs.mean(axis=0) # 平均池化成一个文档向量
doc_vec = doc_vec / np.linalg.norm(doc_vec) # 池化后必须再归一化
print(doc_vec.shape) # 维度不变,语义已被平滑
处理方式对比
| 方式 | 适用情况 | 风险 |
|---|---|---|
| 直接截断 | 信息集中在文档开头 | 尾部章节永远检索不到 |
| 分块后平均池化 | 内容均匀、无单一主题 | 主题发散时被平均成模糊中心 |
| 分块逐块入库 | 长文档、内容密度高 | 切片数量增加,检索与重排成本上升 |
| 换长文本模型 | 确有超长输入需求 | 推理更慢,单条成本更高 |
截断与池化都会改变向量语义,两种策略先在评测集上对比再定;直接上线会让召回变化难以归因。
核对块长度要用 token 数而不是字符数:中英混排下同样字数的 token 数差异很大,按字符数配置容易出现实际超限。