Windows下LangChain调用Falcon-7b-instruct报SIGALRM属性错误求助
解决Windows下Streamlit调用本地falcon-7b-instruct时的
signal.SIGALRM错误 错误原因
SIGALRM是类Unix系统专属的信号,LangChain的HuggingFacePipeline组件默认使用依赖该信号的超时处理逻辑,在Windows环境下会触发AttributeError: module 'signal' has no attribute 'SIGALRM'。该问题并非Streamlit的Windows兼容性问题,而是LangChain跨平台适配的问题。
同时你的代码存在两处基础错误,会加剧运行异常:
- 用
AutoModelForSeq2SeqLM加载falcon-7b-instruct:falcon是自回归因果语言模型,应使用AutoModelForCausalLM - 错误指定pipeline任务为
text2text-generation:因果模型对应的任务是text-generation
解决步骤及修正代码
1. 修正模型加载与pipeline配置
替换错误的模型加载类和任务类型,同时添加显存优化配置(可选)。
2. 禁用LangChain的SIGALRM超时逻辑
在初始化HuggingFacePipeline时,通过model_kwargs设置timeout=None,跳过依赖SIGALRM的超时检查。
修正后的完整代码:
from langchain.llms import HuggingFacePipeline import torch from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline model_id = 'tiiuae/falcon-7b-instruct' tokenizer = AutoTokenizer.from_pretrained(model_id) # 修正:用AutoModelForCausalLM加载因果模型 model = AutoModelForCausalLM.from_pretrained( model_id, torch_dtype=torch.bfloat16, # 降低显存占用,需GPU支持,无GPU可改为torch.float32 device_map="auto" # 自动分配模型到GPU/CPU ) # 修正:使用text-generation任务 pipe = pipeline( "text-generation", model=model, tokenizer=tokenizer, max_new_tokens=100, # 控制生成文本长度,替代max_length更准确 temperature=0.7, do_sample=True ) # 禁用基于SIGALRM的超时处理 chat = HuggingFacePipeline( pipeline=pipe, model_kwargs={"timeout": None} ) # 初始化RetrievalQA并运行 qa = RetrievalQA.from_chain_type(llm=chat, chain_type="stuff", retriever=db.as_retriever()) st.success(qa.run(query))
可选进阶方案(如需超时处理)
如果需要为模型推理添加超时限制,可自定义基于线程的超时装饰器,替代LangChain默认的信号式超时:
import threading class TimeoutException(Exception): pass def timeout_handler(func, timeout_seconds): def wrapper(*args, **kwargs): result = None exception = None def target(): nonlocal result, exception try: result = func(*args, **kwargs) except Exception as e: exception = e thread = threading.Thread(target=target) thread.start() thread.join(timeout_seconds) if thread.is_alive(): raise TimeoutException(f"推理超时({timeout_seconds}秒)") if exception: raise exception return result return wrapper # 使用时包装qa.run方法 timeout_run = timeout_handler(qa.run, 30) # 设置30秒超时 try: st.success(timeout_run(query)) except TimeoutException as e: st.error(str(e))
内容的提问来源于stack exchange,提问作者natedev
相关产品推荐
相关产品推荐

