最近在把一个基于LangChain的RAG服务部署到生产环境,用的vLLM跑Qwen2.5-7B,向量库是Milvus。本地测试时感觉还行,但上线后并发一上来就发现首token延迟飙到3-5秒,用户反馈很卡。自己看了下链路,感觉是检索和LLM生成串行导致的,但不确定瓶颈到底在embedding、向量检索还是prompt拼接上。也试过调vLLM的prefill参数,但效果不明显。想问下大佬们,这种场景一般怎么优化?是走rerank加缓存,还是把检索和生成改成异步,或者直接上更小的模型?希望有实战经验的朋友能指点一下,先谢过了。
RAG部署后首token特别慢,有什么优化思路吗?
全部回复
共 6 条并发上来首token飙到3-5秒,大概率不是vLLM的问题,我遇到过类似情况,瓶颈往往在embedding和向量检索的排队上。你可以先给Milvus加个连接池,然后把embedding单独拆个服务,这样至少能隔离掉一部分延迟。另外,如果业务允许,把top-k调小点或者加个简单的关键词预筛,比直接上rerank性价比高。缓存倒是建议先做,尤其是高频query,能省不少事。你测过纯LLM首token在空跑时的基准是多少吗?这能帮你定位到底哪段链路吃掉了时间。
我之前也踩过这个坑,实测下来瓶颈往往不在vLLM本身,而是LangChain默认的检索和生成完全串行,建议先给Milvus的检索加个并发,或者把embedding丢到独立进程里,能快不少。另外rerank别急着上,先试试给高频query加个简单的语义缓存,命中率上来后首token能压到1秒内。你这个延迟如果是偶发性的,大概率是prompt拼接里塞了太多历史消息,把模板精简下可能立竿见影。最后想问下,你的vLLM是开的continuous batching吗,并发高的时候prefill和decode混排会影响首token,试试调下max-num-seqs。
并发一上来首token慢,大概率不是模型本身的问题,而是检索链路串行拖的。你可以先打个时间戳埋点,把embedding、Milvus查询、prompt拼接这三段分别测一下,基本就能定位了。我这边经验是Milvus在并发高的时候查询抖动挺明显,加个本地LRU缓存命中率高的话能省不少。另外vLLM的prefix caching如果prompt前缀固定记得开,对首token帮助比调prefill参数直接。
先查向量检索耗时吧,Milvus并发下经常是它拖后腿,不一定是LLM的锅。
先查下检索耗时占比,如果Milvus查询就占了大头,那调vLLM纯属白费劲。异步化确实值得搞,但别忘了prompt拼太长也会拖慢prefill。
我之前也踩过这个坑,首token慢大概率是检索那段卡住了,尤其Milvus并发一高、没建好索引的话延迟很吓人。建议先把embedding和检索的耗时打点看清楚,别急着换模型。另外prompt拼接如果太长,prefill确实会拖慢,但3-5秒更像是检索侧的问题。可以试试加个语义缓存,命中率高的话首token能降不少。