你可能已经按教程把 RAG-Anything 装好了,Ollama 也拉起了模型,可一喂图片和 PDF 就开始卡:视觉模型和文本模型走哪个端点、超时设多少、并发一高就排队、解析失败还没日志。这篇不重讲原理,只按工程落地顺序,把对接 Ollama 时要定的配置项、要留的开关和出问题先看哪儿讲清楚。
你可能已经按教程把 RAG-Anything 装上了,Ollama 那边也把模型拉起来了,可一喂图片和 PDF 就开始卡:视觉模型和文本模型到底走哪个端点、超时给多少、并发一高就排队、解析失败还翻不到日志。这篇不重讲原理,只按工程落地顺序,把对接 Ollama 时要提前定的配置项、要留的开关、出问题先看哪儿讲清楚。
整篇的节奏是这样的:先定模型分工,再定超时和重试,然后限定并发数,接着把降级路径设计出来,最后把日志和评测补上。每一步都能单独停下来验证,不用一次全改完。如果只挑一件事做,那就是先把「一次请求里哪一步慢、哪一步错」记下来,后面所有调参都靠这份记录。
先把模型分工定下来,再动配置文件
RAG-Anything 的多模态链路一般要两类角色:一类管文字生成与改写,一类管图片理解或图片描述。别指望一个模型全包,尤其是本地小模型,理解图里的表格和数字本来就吃力。先把这两类模型在 Ollama 里各自单独跑通,确认能出结果,再去填框架配置,顺序反了会浪费很多排查时间。
- 文本模型
- 负责问题改写、片段拼装、最终作答,对速度敏感
- 视觉模型
- 负责图片描述、图表读数,对显存和首次加载时间敏感
- 兼容端点
- 框架只认某一种接口形状时走兼容模式,字段口径差异到 /ai-dict/category/tech 对照
- 错峰加载
- 显存不够时让两个模型轮流驻留,而不是同时抢资源
- 先在命令行单独调两类模型各一次,确认本地能跑通再进配置
- 确认框架支持的接口形状,走兼容端点时逐字段核对请求体,字段口径到 /ai-dict/category/tech 对照
- 视觉能力弱的模型别硬上图片链路,先关掉图片通道只跑文本,跑稳再逐步开
- 本地显存或内存紧张时把两个模型错峰加载,避免同时驻留互相挤爆
- 端点写法可参考 /official-api/providers 里同类本地部署的入口说明,别自己猜路径
超时与重试:本地推理不能用云端那套默认值
Ollama 首次加载模型会有冷启动,第一次请求比后面慢很多,这是本地推理和云端最不一样的地方。所以连接超时和读取超时要分开设:连接超时不用给太大,读取超时要给足。把两者混成一个值,要么冷启动必失败,要么正常请求白等很久。实际延迟基线先用 /tools/speed-test 量一遍,再决定数值,别照抄别人的配置。
| 参数 | 设太大 | 设太小 |
|---|---|---|
| 连接超时 | 故障藏得深,卡住不报错 | 冷启动直接被拒 |
| 读取超时 | 单请求挂很久,拖住队列 | 带图请求频繁超时 |
| 重试次数 | 排队错误被反复放大 | 偶发失败直接暴露给用户 |
| 重试退避 | 恢复变慢 | 打回去就是二次排队 |
- 可重试:连不上、连接被拒、偶发超时
- 要带退避再重试:模型正在加载返回的排队类错误,立刻打回去只会更堵
- 不可重试:请求体格式错误、模型不存在,重试多少次都一样
- 按请求类型分档设超时:纯文本一档、带图一档,带图那档明显放宽
- 改完超时值先用几条带图和纯文本的请求各跑一遍,看日志里的阶段耗时再定稿
重试还有个容易忽略的点:重试会放大并发。本来并发是 N,一个请求重试两次就变成瞬时 3N,本地单机很容易被打爆。所以重试次数别给多,退避要留够,最好把重试也纳入后面的并发计数里统一考虑。
并发别一次性拉满,排队比报错好处理
本地单机推理的并发能力有限,框架侧的并发数要和 Ollama 那边的并行能力对齐,超了就是排队或直接失败。判断自己到没到顶,不是等报错,而是看延迟。逐步加并发,如果某个值之后延迟出现明显台阶,那就是到顶了,拐点前一个档位才是安全值。
- 定基线单并发跑固定一批请求,记下平均和尾部耗时,作为后面比较的基准
- 逐步加并发每次加一点,观察延迟曲线,出现台阶就说明到了瓶颈
- 回退一档把并发设到拐点前一个档位,留出余量,不要贴着极限跑
- 分批入库批量文档按批喂,每批之间留间隔,失败的那批单独重投,不要整批回滚重跑
- 验证压测后看日志里有没有排队类错误,有就继续往下调
图片解析是耗时大头,建议把图片通道单独排队、单独限并发,避免它拖慢文字检索的响应。很多场景下用户问的是文字问题,却因为图片队列堵着一起变慢,这种体验下降完全可以在配置层避免。
降级路径提前设计好
降级不是可有可无的装饰,而是多模态链路的保险。图片理解失败时降级为只返回文本片段加图片位置提示,比整条回答直接失败体验好得多。视觉模型不可用时,可以切到一个轻量的描述策略,或者干脆跳过图片通道,同时在返回里标注「未使用图片证据」,让下游知道这次答案的证据范围。
| 故障 | 降级动作 | 要不要标记 |
|---|---|---|
| 单张图理解失败 | 跳过该图,保留文本片段与图片位置 | 要,标在返回里 |
| 视觉模型不可用 | 跳过图片通道,只跑文本检索 | 要,注明未用图片证据 |
| 带图请求超时 | 按类型重试一次,仍失败则降级 | 要,记入日志 |
| 强依赖图表数据 | 不降级,直接报错让人介入 | 必记录失败原因 |
什么情况不适用降级:如果业务强依赖图片里的数字或表格,比如对账、报价这类场景,就不能随便降级成纯文本,应该直接报错让人介入。降级的前提是「少一点证据也能给个有用回答」,前提不成立就别降。
日志与评测:让一次请求的慢和错能复盘
日志不用记一大堆,抓住几项就够定位大部分问题:请求类型(文本还是带图)、命中的模型名、各阶段耗时、召回条数、是否触发降级。有了这几项,一次请求是慢在加载、慢在推理还是慢在检索,一眼能分出来。没有这些,调参就只能靠感觉。
- 请求类型与命中的模型名,用来区分是哪个通道出的问题
- 各阶段耗时,用来判断瓶颈在加载、推理还是检索
- 召回条数与是否命中图片通道,用来判断证据够不够
- 是否触发降级,以及降级原因,避免把降级当真实水平
- 固定一小批问题做成回归集,配置改完跑一遍对比,别凭感觉说变好了
多模态检索的评测要分开看:文本召回准不准、图片召回准不准、拼装后答案准不准,三段混在一起就看不出来是哪一段坏了。解析和切分是否合理,可以到 /tools/quality-check 类页面做交叉检查,别只信自己那一套切分方式。
下一步先把模型分工和超时基线定下来,再去 /tools/speed-test 量一遍本地延迟,用当时的真实数字决定超时和并发;模型与端点口径方面的疑问,到 /ai-dict/category/tech 对照着看。→常见问题
RAG-Anything 对接 Ollama 时,图片一直识别不出来,先查哪?
按顺序查三处:一是给图片通道配的模型本身有没有视觉能力,单独用命令行试一次;二是请求有没有真的带上图片内容,日志里看请求类型字段;三是超时是不是太短,带图请求普遍更慢,冷启动时更明显。三处都正常再看返回里有没有静默降级。
本地跑多模态检索很慢,是先加硬件还是先调配置?
先调配置。把并发降到单机吃得下的水平、给读取超时留足、把图片通道和文字通道分开排队,往往就能改善一大截。确认真的是算力到顶了再加硬件,判断办法是加并发后延迟有没有明显台阶式上涨。
配置改完之后,怎么确认整体是变好还是变坏?
准备一小批固定问题,覆盖纯文本、带图、图片里有关键信息这几类,每次改完跑一遍,记录命中情况和耗时。只看单个案例感觉不准,容易把某次侥幸当成提升。评测口径和指标含义可到 /benchmarks 对照查看。