使用ChromaDB构建LangChain QA系统时遇token超限错误求助
解决"llama_tokenize_with_model: too many tokens"及ValueError问题
这个问题核心是长文本语料转换为令牌后,超出了LLaMA模型的上下文窗口限制,短文本因令牌数少不受影响,调整以下参数即可解决:
1. 调整文本分割参数(最关键)
把大段语料拆成符合模型令牌限制的小片段,使用RecursiveCharacterTextSplitter时重点调整这两个参数:
chunk_size:设为模型最大上下文长度的70%-80%(比如LLaMA-7B是4096,就设3000左右)chunk_overlap:设50-200,保证片段间有上下文衔接,避免语义断裂
示例代码:
from langchain.text_splitter import RecursiveCharacterTextSplitter text_splitter = RecursiveCharacterTextSplitter( chunk_size=3000, chunk_overlap=100, length_function=len, ) docs = text_splitter.split_documents(your_long_corpus)
2. 限制LLM的上下文和输出令牌数
初始化LLM模型时,明确设置上下文窗口和最大输出令牌数,确保输入+输出的总令牌不超模型上限:
比如用LlamaCpp时:
from langchain.llms import LlamaCpp llm = LlamaCpp( model_path="./llama-model.gguf", n_ctx=4096, # 必须和你的LLaMA模型上下文窗口一致,比如7B模型是4096 max_tokens=2048, # 设为小于n_ctx的值,留足空间给输入令牌 )
3. 减少检索返回的文档片段数
使用RetrievalQA时,调小retriever的k值,减少拼接后输入LLM的令牌总量:
from langchain.chains import RetrievalQA qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="stuff", retriever=vectorstore.as_retriever(k=3), # 把k从默认值调到2-3 return_source_documents=True )
4. 更换链类型适配长文本
如果用的是stuff链类型,它会把所有检索到的文档直接拼接输入LLM,极易超令牌。换成map_reduce或refine链类型:
map_reduce:先单独处理每个片段,再合并结果,适配长文本场景refine:基于之前的结果逐步优化,语义连贯性更好但速度稍慢
示例切换链类型:
qa_chain = RetrievalQA.from_chain_type( llm=llm, chain_type="map_reduce", retriever=vectorstore.as_retriever(k=4), return_source_documents=True )
内容的提问来源于stack exchange,提问作者adhok
相关产品推荐
相关产品推荐

