Mistral 7B在ConversationalRetrievalChain中遇上下文长度超限错误
解决Mistral 7B构建ConversationalRetrievalChain时的Token超限与无关响应问题
问题分析
你遇到的核心问题有两个:
- Token超限错误:输入总token数(760)超过模型设置的最大上下文长度(512),原因是CTransformers默认上下文长度未匹配Mistral 7B的原生8k窗口,且检索返回的文档+查询的总token超出限制。
- 无关响应:每次循环重置
chat_history导致模型无法正确理解对话上下文,同时超限错误也会引发模型生成混乱输出。
针对性解决方案
1. 匹配模型原生上下文窗口
Mistral 7B-v0.1原生支持8192 token的上下文长度,初始化CTransformers时需显式设置该参数,覆盖默认的512限制:
llm = CTransformers(model="models/mistral-7b-v0.1.Q4_0.gguf", model_type="llama", max_new_tokens=1000, temperature=0.1, context_length=8192) # 显式设置模型支持的最大上下文长度
2. 限制检索返回的文档数量
减少检索器返回的文档数,降低输入到模型的文本总量,避免token超限:
qa = ConversationalRetrievalChain.from_llm(llm, retriever=docsearch.as_retriever(search_kwargs={"k": 2})) # 限制返回2条相关文档
3. 优化文本分割尺寸
调小文本块的chunk_size,控制单个文本块的token数量,叠加后更不易超限:
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=20) # 将单块尺寸从500调整为300
4. 正确维护对话历史
将chat_history移到循环外部,确保对话上下文能被持续保留,避免模型输入格式异常:
chat_history = [] # 移到循环外初始化 while True: query = input(f"Input Prompt: ") if query == 'exit': print('Exiting') sys.exit() if query == '': continue result = qa({"question":query, "chat_history":chat_history}) print("Response: ", result['answer']) chat_history.append((query, result['answer'])) # 追加对话历史
修改后的完整代码
from langchain.document_loaders.csv_loader import CSVLoader from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.embeddings import HuggingFaceEmbeddings from langchain.vectorstores import FAISS from langchain.llms import CTransformers from langchain.memory import ConversationBufferMemory from langchain.chains import ConversationalRetrievalChain import sys DB_FAISS_PATH = "vectorstore/db_faiss" loader = CSVLoader(file_path="data/World Happiness Report 2022.csv", encoding="utf-8", csv_args={'delimiter': ','}) data = loader.load() print(data) # Split the text into Chunks - 优化文本块尺寸 text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=20) text_chunks = text_splitter.split_documents(data) print(len(text_chunks)) # Download Sentence Transformers Embedding From Hugging Face embeddings = HuggingFaceEmbeddings(model_name = 'sentence-transformers/all-MiniLM-L6-v2') # Converting the text Chunks into embeddings and saving the embeddings into FAISS Knowledge Base docsearch = FAISS.from_documents(text_chunks, embeddings) docsearch.save_local(DB_FAISS_PATH) # 初始化LLM - 设置正确的上下文长度 llm = CTransformers(model="models/mistral-7b-v0.1.Q4_0.gguf", model_type="llama", max_new_tokens=1000, temperature=0.1, context_length=8192) # 构建检索链 - 限制返回文档数量 qa = ConversationalRetrievalChain.from_llm(llm, retriever=docsearch.as_retriever(search_kwargs={"k": 2})) # 对话循环 - 正确维护对话历史 chat_history = [] while True: query = input(f"Input Prompt: ") if query == 'exit': print('Exiting') sys.exit() if query == '': continue result = qa({"question":query, "chat_history":chat_history}) print("Response: ", result['answer']) chat_history.append((query, result['answer']))
效果说明
通过以上修改:
- 充分利用Mistral 7B的8k上下文窗口,避免token超限错误;
- 减少检索文档数量和单块文本尺寸,精准控制输入token总量;
- 正确维护对话历史,让模型能基于上下文生成连贯、相关的响应。
内容的提问来源于stack exchange,提问作者Anshu Singh
相关产品推荐
相关产品推荐

