Ollama 向量入库静默截断 2048 token:超出部分对检索贡献是精确的零

排障 · 整篇 vs 切块 / 检索命中对照L1整理于 2026-10-17 有效期 30d

Ollama /api/embed 在模型上下文上限处静默截断:文档超 2048 token 后接口照返 200、照给 768 维向量,无任何报错。实测 2600 字与 4000 字的文档,向量余弦相似度 1.00000000(完全相同)。严格等长对照(5 份均 3108 字、4 份逐字相同,答案只放第 3 份):答案放在开头时该文档相似度 0.685300,与其余 0.622509 可区分;答案挪到末尾则 0.622509 与无答案文档差 +0.000000,完全无法区分。改为按 400 字切块后,开头 0.717245 / 末尾 0.682265,均恢复可区分。修法是切块而非换更大的模型。

Ollamaembedding向量检索知识库RAG本地部署prompt_eval_count截断

这条适用于

版本指纹

Windows 11 + RTX 5090D 32GB;Ollama 0.40.4;nomic-embed-text:latest(F16 / 137M / context 2048)

具体做法

环境:本机 RTX 5090D 32GB / Ollama 0.40.4 / nomic-embed-text:latest(F16、137M 参数、context_length 2048),2026-10-17。

【长度 → prompt_eval_count】(同一段中文逐步加长)
· 200 字 → 202
· 600 字 → 602
· 1200 字 → 1202
· 1500 字 → 1502
· 2000 字 → 2002
· 2500 / 3000 / 4000 / 6000 字 → 一律 2048

【相邻档余弦相似度(截断后向量是否相同)】
· 2200 → eval 2048,cos(上一档) = 0.99986134
· 2600 → 2048,cos(上一档) = 1.00000000
· 3000 → 2048,cos(上一档) = 1.00000000
· 4000 → 2048,cos(上一档) = 1.00000000
· 6000 → 2048,cos(上一档) = 1.00000000
→ 2600 字文档与 4000 字文档得到完全相同的 768 维向量。

【token 折算实测(chars/token)】
· 纯中文 0.990
· 纯英文 5.098
· 真实技术文本 1.596(样本:这台机器上我用 ComfyUI 出图,SDXL base 1.0,1024x1024,seed 固定,显存 9134MiB,耗时 2.259s。)
→ 2048 token 约等于 1283 字符。一份 2500 字技术文档,从第一页读完之前后面已被丢弃。

【严格等长对照实验】
5 份文档均 3108 字符 / 2048 token;其中 4 份逐字完全相同;正确答案只放在文档3,分别置于开头与末尾两种位置,提问固定。
· 整篇 embedding(默认做法):
  - 答案在开头 → 文档3 cos 0.685300,其余 0.622509,差 +0.062791(可区分)
  - 答案在末尾 → 文档3 cos 0.622509,与无答案文档 0.622509,差 +0.000000(完全无法区分)
  - 文档里根本没有 → 差 +0.000000
· 按 400 字切块取最高分:
  - 答案在开头 → 0.717245
  - 答案在末尾 → 0.682265(恢复可区分)
  - 无答案 → 0.650749

【耗时与批量】
· 同一份 3108 字文档:整篇一次 0.0422 s;切 8 块全算 0.1893 s(多 0.147 s)
· 240 份:逐条 4.793 s(50.07 份/秒)vs 批量 input 数组 1.359 s(176.64 份/秒),差 3.53 倍

【truncate 参数行为】
· 默认(不传):静默截断,返 200 + 768 维向量
· truncate = false:HTTPError the input length exceeds the context length
【确定性核验】
· 同文本连测 6 次:md5 全部 fc91d154de1b(唯一哈希数 = 1)
· 该文本夹在两次长文本请求之间:cos(v0,v1)=1.0000000000、cos(v0,v2)=1.0000000000
· 批量数组第 4 项 vs 单条:cos=1.0000000000,md5 相同
失效边界
本结论为本机实测(2026-10-17;RTX 5090D 32GB / Ollama 0.40.4 / nomic-embed-text:latest,上下文长度 2048、F16、137M 参数)。测试前已停止本机其他占卡任务,避免显存与耗时被污染。截断阈值由「长度 → prompt_eval_count 映射」与「相邻档向量恒等」双重判定,未读模型源码,属行为层实证。token 折算率随文本成分变化较大(纯中文 0.990 / 纯英文 5.098 / 混合技术文本 1.596),换其他语料需重测,不可直接套用。换用上下文更长的 embedding 模型可抬高截断线,但同一份超长文档仍会稀释,切块仍是通用解。
← ffmpeg 拼片头不该重编:加 7 秒,全片被重走一遍编码器本地 14B 写长文有天花板:要 5000 字只给 2400,且它自己认为写完了 →

← 返回全部排错方案