做 RAG 的人多半是这么卡住的:生成模型已经跑通了,轮到向量化那一步才发现 Ollama 上嵌入模型是另一套用法——模型要单独拉、接口走的是 embeddings 而不是 chat、返回的向量维度和长度限制也跟对话模型不是一回事。这篇按「先选、再拉、再调、最后验」的顺序走一遍,每一步给判断标准和可执行的命令思路,帮你把嵌入这一环接进自己的知识库流程。
做 RAG 的人多半是这么卡住的:生成模型已经跑通了,轮到向量化那一步才发现 Ollama 上嵌入模型是另一套用法。模型要单独拉,接口走的是 embeddings 而不是 chat,返回的向量维度和长度限制也跟对话模型不是一回事。这篇按「先选、再拉、再调、最后验」的顺序走一遍,每一步给判断标准和可执行的命令思路。
需要先说清一个前提:下面讲的是把嵌入这一环接进自己的知识库流程。如果你现在只是做纯关键词匹配,或者团队已经在用成熟的托管检索服务,那本文大部分步骤可以跳过,硬接反而增加维护成本。
先定用哪个嵌入模型
选型别只看排行榜。嵌入模型决定的是「找得准不准」,它跟生成模型是两条线,可以来自完全不同的系列。筛的时候按三个维度过一遍:中文语义效果、向量维度、单条输入长度上限。维度越高,向量库的存储和检索开销越大,不是越高越好,要跟你的知识库规模一起算。
- 中文知识库优先看站内嵌入模型专题里针对中文检索的整理,别直接照搬英文榜单结论
- 先量一下自己文档的单条长度分布,再对比候选模型的输入上限,超长文档要提前规划切分
- 确认向量维度后再定向量库表结构,维度定错会导致后续所有写入失败
- 模型清单和规格以站内页面当时的数据为准,别人博客里的名字和参数经常已经过期
拉模型并确认它真能出向量
拉取本身只是一条命令,关键是拉完要验证它真的在出向量,而不是加载成功但输出异常。验证分三步做,每步都能独立判断成败,出问题时好定位。
- 最短文本试跑用一条很短的文本发一次嵌入请求,确认返回的是定长浮点数组,而不是报错或者空结果
- 记录实测维度把返回数组的长度记下来,跟向量库建表时的维度设置对齐,错一位后面全部写入失败
- 换句再跑一次换一条含义明显不同的短句再跑,看两组向量是否可区分,避免输出退化成常量
- 核对模型变体嵌入模型常被量化或改名,拉到的到底是哪个变体,去站内模型详情页核对,对不上就换个来源重拉
| 验证项 | 通过标准 | 不通过时先做什么 |
|---|---|---|
| 接口连通 | 能返回数组且无报错 | 检查服务地址和端口 |
| 维度一致 | 实测长度等于建表维度 | 改表结构或换模型 |
| 输出可区分 | 两条不同文本的向量不接近 | 确认加载的是嵌入模型 |
| 变体正确 | 与详情页标注一致 | 换来源重新拉取 |
在代码里怎么调这个接口
嵌入走的是专门的向量接口,路径和对话生成不一样,参数里也没有温度、上下文这类对话项。照着文档传对应的文本字段就行。团队里最好固定一种调用方式,Python 和 HTTP 别混着用,否则排查问题时两边参数口径对不上,光对齐字段就要花半天。
批量场景一次传多条比循环单条快,但要注意单次条数上限和总长度上限,超了会被截断或直接报错。返回结果写进向量库之前,先做一次长度校验和空值过滤,脏数据进了库只能重建索引。
# 调用思路示意,具体字段名以站内接口文档为准\ncurl http://localhost:11434/api/embeddings \\\n -d '{"model":"<你的嵌入模型名>","prompt":"<一段测试文本>"}'- 一次请求的文本条数控制在文档说明的上限内,超了就分批
- 对返回向量做长度断言,长度不对直接抛错,别静默写库
- 空字符串和纯空白输入提前过滤,这类输入有的模型会返回异常向量
- 把模型名和维度写进配置,别散落在代码各处
不工作时按这个顺序排查
嵌入接口报错时,最忌讳上来就换模型。按下面这个顺序走,绝大多数问题在前两步就能定位,第五步之前都不用怀疑模型本身。
- 先看服务在不在本地端口能不能通,连不上先解决连接问题,跟模型无关
- 再看模型在不在列表里有没有这个嵌入模型,名字有没有拼错,有没有误用了对话模型的名字
- 然后看输入超长文本、空字符串、全是特殊符号,都会导致报错或者质量异常,先拿一条正常短文本复现
- 接着看资源嵌入模型也要占显存或内存,跟生成模型同时加载时可能互相挤,先只跑嵌入看是否恢复
- 最后才换模型换之前把上面四步的日志留好,否则换了也只是碰运气
嵌入这一环出问题,八成不是模型不行,是维度、输入或资源这三样里有一个没对齐。下一步把候选嵌入模型的规格、向量维度和输入上限拉到一张表里对比,再决定用哪个。站内嵌入模型专题页有整理好的对照信息,去核对当时的数字比翻博客靠谱。→
常见问题
为什么我用对话模型的接口去做向量化,效果很差?
对话模型和嵌入模型是两个训练目标:一个生成文字,一个输出定长向量。用对话模型硬取中间层或让它输出数字,语义稳定性差很多。做检索请专门拉一个嵌入模型,两条链路分开跑,各占各的资源。
嵌入模型和生成模型能同时挂在一个 Ollama 上吗?
可以,只要显存或内存够。两者是独立加载的,请求也走不同接口。但如果资源紧张,同时驻留会拖慢生成速度,可以按需先跑完离线向量化、再切回生成模型,或把嵌入放到另一台机器上。
向量化一次要跑多久,文档多了怎么办?
取决于文本长度、批量大小和硬件,没法给一个固定数。务实做法是先拿一小批文档跑通、量出自己机器的处理节奏,再决定是全量重跑还是增量更新;已有向量库的情况下,只对新增和改动的文档做嵌入。