ConversationalRetrievalChain调大k值触发Token超限问题求助
解决ConversationalRetrievalChain增大k值时的令牌超限问题
当使用ConversationalRetrievalChain检索器时,增大返回文档数参数k(例如设为10)会触发令牌数超过模型最大上下文长度的警告,具体错误提示:
WARNING:ctransformers:Number of tokens (1554) exceeded maximum context length (512).
默认k=4时运行正常,但CSV数据有1000行,需要更大的k值覆盖更多相关数据,以下是可行的解决方法:
1. 调整LLM的上下文长度参数
你使用的Llama-2-7B-GGUF模型实际支持4096的上下文长度,但CTransformers初始化时默认可能限制为512。需要显式设置context_length参数:
llm = CTransformers(model=llm_model_name, model_type='llama', max_new_tokens=8145, temperature=1.0, context_length=4096) # 设置为模型支持的最大上下文长度
同时,ConversationalRetrievalChain的max_tokens_limit要预留足够空间给生成的新令牌,建议设为3500:
qa = ConversationalRetrievalChain.from_llm(llm, retriever=db2.as_retriever(search_kwargs={'k': 10}), memory=memory, output_key="answer", verbose=True, max_tokens_limit=3500) # 匹配上下文长度,预留生成空间
2. 优化文本分块大小
当前chunk_size=200的分块可能过大,导致单文档块令牌数较多,k=10时总令牌数超限。可以减小分块大小并增加重叠度,保证上下文连贯:
text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=20) # 减小分块大小,增加重叠 docs = text_splitter.split_documents(documents)
这样每个文档块的令牌数减少,即使k=10,总令牌数也更容易控制在上下文长度内。
3. 检索后按令牌数筛选文档
先检索更多文档,再根据令牌总数过滤掉超出部分,避免一次性传入过多内容:
from langchain.schema import Document from transformers import AutoTokenizer # 初始化模型对应的tokenizer tokenizer = AutoTokenizer.from_pretrained("TheBloke/Llama-2-7B-GGUF") def filter_docs_by_token_count(docs, max_total_tokens): total_tokens = 0 filtered_docs = [] for doc in docs: doc_tokens = len(tokenizer.encode(doc.page_content)) if total_tokens + doc_tokens <= max_total_tokens: filtered_docs.append(doc) total_tokens += doc_tokens else: break return filtered_docs # 先检索20条文档,再筛选到令牌数上限内 retriever = db2.as_retriever(search_kwargs={'k': 20}) filtered_docs = filter_docs_by_token_count(retriever.get_relevant_documents(traducao), 3500) # 将筛选后的文档传入链中(可自定义链逻辑或使用RetrievalQAWithSourcesChain)
4. 切换到更大上下文窗口的模型
如果上述方法仍无法满足需求,可更换为支持更大上下文的模型,比如Llama-2-7B-32K-GGUF,它支持32768的上下文长度:
llm_model_name = "TheBloke/Llama-2-7B-32K-GGUF" llm = CTransformers(model=llm_model_name, model_type='llama', max_new_tokens=8145, temperature=1.0, context_length=32768)
内容的提问来源于stack exchange,提问作者Renan
相关产品推荐
相关产品推荐

