# Qwen3.5在Transformers库部署推理及ReAct智能体
0 目录前言Transformers库常用AutoModel介绍常见的AutoModel类使用方式纯文本推理文本图片推理ReAct工具执行推理参考资料1 前言Qwen3.5系列发布好些天了官方的ModelCard只有SGLang、vLLM、KTransformers等框架的推理示例以及OpenAI库、Agentic智能体的使用方法但是对于初学者来说仍然有在Transformers库上加载大模型进行推理和微调训练的学习需求本文就是为此所撰写的。2 Transformers库常用AutoModel介绍有时候我们总会对AutoModel、AutoModelForCausalLM等类产生疑惑这些有什么区别可以说AutoModel是backbone而AutoModelForXXX是在backbone基础上针对任务做了进一步的处理。语言建模通常有因果型和掩码型这是为了区分但是针对视觉语言模型则AutoModelForCausalLM并不适用而应该使用AutoModelForImageTextToText。2.1 常见的AutoModel类类名描述适用任务AutoModel加载预训练的基础模型不包含任务特定任务的头部特征提取、嵌入生成等AutoModelForCausalLM加载带有因果语言建模头部的模型适用于生成任务文本生成、文本补全、对话等AutoModelForMaskedLM加载带有掩码语言建模头部的模型适用于填空任务。命名实体识别、文本填空等AutoModelForImageTextToText加载接受图像输入的语言模型适用于视觉问答多模态处理任务图像理解图像分割文本生成等3 使用方式库引用importtorchimportrequestsfromPILimportImagefromaccelerateimportAcceleratorfrommodelscopeimportsnapshot_download model_dirsnapshot_download(Qwen/Qwen3.5-2B)deviceAccelerator().device3.1 纯文本推理fromtransformersimportAutoModelForCausalLM,AutoTokenizer# 加载因果语言模型纯文本模型适用于生成任务modelAutoModelForCausalLM.from_pretrained(model_dir,torch_dtypetorch.float16,# 使用float16nvidia卡可使用torch.bfloat16trust_remote_codeTrue).to(device)# 注 可添加device_mapauto参数自动分配设备支持多卡# 加载分词器tokenizerAutoTokenizer.from_pretrained(model_dir,trust_remote_codeTrue)# 构建对话消息messages[{role:assistant,content:[{type:text,text:you are a helpful assistant.},]},{role:user,content:[{type:text,text:什么是LLM什么是VLM两者有何区别},]}]# 应用chat_template格式化输入texttokenizer.apply_chat_template(messages,tokenizeFalse,add_generation_promptTrue)# 编码输入inputstokenizer(text,return_tensorspt).to(device)# 前向推理生成回复withtorch.no_grad():generated_idsmodel.generate(**inputs,max_new_tokens1024)# 解码输出input_lenlen(inputs.input_ids[0])# 输入长度generated_texttokenizer.decode(generated_ids[0][input_len:],skip_special_tokensTrue)print(f模型回复:{generated_text})3.2 文本图片推理3.2.1 导入库fromtransformersimportAutoModelForImageTextToText,AutoProcessor3.2.2 加载模型和处理器# 加载图像文本转文本模型视觉语言模型适用于接受图像输入的语言模型modelAutoModelForImageTextToText.from_pretrained(model_dir,dtypetorch.float16).to(device)# 初始化处理器processorAutoProcessor.from_pretrained(model_dir,trust_remote_codeTrue)3.2.3 构建对话消息和推理# 构建对话消息messages[{role:user,content:[{type:image,image:http://images.cocodataset.org/val2017/000000039769.jpg},{type:text,text:在这张图片里你能看到什么},]}]# 调用处理器processors应用聊天模板预处理其输出与图像输入inputsprocessor.apply_chat_template(messages,add_generation_promptTrue,tokenizeTrue,return_dictTrue,return_tensorspt).to(device)# 前向传播将预处理后的输入传递给模型withtorch.no_grad():generated_idsmodel.generate(**inputs,max_new_tokens200)# 解码模型输出input_lenlen(inputs.input_ids[0])generated_textsprocessor.batch_decode(generated_ids[:,input_len:],skip_special_tokensTrue)print(generated_texts)3.2.4 图像输入的格式格式类型示例写法说明URL“http://images.cocodataset.org/val2017/000000039769.jpg”网络图片链接本地路径“/path/to/your/image.jpg”注意file://前缀Base64“/9j/4AAQSkZJRg…”Base64编码字符串本地路径messages [ { role: user, content: [ {type: image, image: 000000039769.jpg}, {type: text, text: 在这张图片里你能看到什么}, ] } ] inputs processor.apply_chat_template( messages, add_generation_promptTrue, tokenizeTrue, return_dictTrue, return_tensorspt ).to(device)Base64importbase64fromPILimportImagefromioimportBytesIOdefpil_to_base64(image,format:strJPEG): 将PIL Image转为processor可识别的base64字符串格式 # 内存中保存为字节流bufferedBytesIO()imageimage.convert(RGB)image.save(buffered,formatformat)# 转base64编码b64_strbase64.b64encode(buffered.getvalue()).decode(utf-8)returnb64_str imageImage.open(000000039769.jpg)image_formatJPEGimage_b64_strpil_to_base64(image,image_format)messages[{role:user,content:[{type:image,image:image_b64_str},{type:text,text:在这张图片里你能看到什么},]}]3.3 ReAct工具执行推理ReActReasoning Acting模式让模型能够思考行动观察循环3.3.2 导入库importtorchimportrequestsfromPILimportImagefromtransformersimportAutoModelForImageTextToText,AutoProcessorfromaccelerateimportAcceleratorfrommodelscopeimportsnapshot_downloadimportre model_dirsnapshot_download(Qwen/Qwen3.5-2B)deviceAccelerator().device3.3.3 加载模型与处理器# 加载模型与处理器modelAutoModelForImageTextToText.from_pretrained(model_dir,dtypetorch.float16).to(device)processorAutoProcessor.from_pretrained(model_dir,trust_remote_codeTrue)3.3.4 定义工具TOOLS[{type:function,function:{name:get_current_temperature,description:获取指定城市的当前温度,parameters:{type:object,properties:{location:{type:string,description:城市名称格式城市, 省份, 国家},unit:{type:string,enum:[celsius,fahrenheit],description:温度单位默认celsius}},required:[location]}}},{type:function,function:{name:get_weather_forecast,description:获取指定城市指定日期的天气预报,parameters:{type:object,properties:{location:{type:string},date:{type:string,description:格式YYYY-MM-DD},unit:{type:string,enum:[celsius,fahrenheit]}},required:[location,date]}}}]defexecute_tool(tool_name:str,tool_args:dict):模拟工具执行实际使用中替换为真实API调用iftool_nameget_current_temperature:return{temperature:26.5,location:tool_args[location],unit:tool_args.get(unit,celsius)}eliftool_nameget_weather_forecast:return{forecast:晴转多云,location:tool_args[location],date:tool_args[date]}return{error:Unknown tool}defparse_qwen_tool_calls(text:str):解析 Qwen 模型的 XML 风格工具调用tool_calls[]# 匹配 function函数名.../function 模式patternrtool_call\nfunction(\w)\n(.*?)\n/function\n/tool_callmatchesre.findall(pattern,text,re.DOTALL)forfunc_name,params_blockinmatches:# 解析参数 parameter参数名\n值\n/parameterparam_patternrparameter(\w)\n(.*?)\n/parameterparamsre.findall(param_pattern,params_block,re.DOTALL)tool_args{key:value.strip()forkey,valueinparams}tool_calls.append({name:func_name,arguments:tool_args})returntool_calls3.3.4 多轮ReAct推理循环# 多轮ReAct推理循环defreact_inference(query:str,tools:list,max_rounds:int3):messages[{role:user,content:[{type:text,text:query}]}]forround_idxinrange(max_rounds):# 1.格式化输入inputsprocessor.apply_chat_template(messages,toolstools,add_generation_promptTrue,tokenizeTrue,return_dictTrue,return_tensorspt).to(device)# 2.模型生成withtorch.no_grad():generate_idsmodel.generate(**inputs,max_new_tokens1024,temperature0.7,top_p0.8,top_k20)# 3.解析输出input_lenlen(inputs.input_ids[0])generated_textsprocessor.batch_decode(generate_ids[:,input_len:],skip_special_tokensTrue)print(generated_texts)generated_textgenerated_texts[0]# 4.检查是否包含工具调用 (Qwen 格式)iffunctioningenerated_text:try:# 解析所有工具调用 (可能同时调用多个工具)tool_callsparse_qwen_tool_calls(generated_text)ifnottool_calls:raiseValueError(未解析到有效的工具调用)# 执行所有工具调用tool_results[]fortool_callintool_calls:tool_nametool_call[name]tool_argstool_call[arguments]# 执行工具tool_resultexecute_tool(tool_name,tool_args)tool_results.append({name:tool_name,result:tool_result})print(f调用工具 [{tool_name}], 参数:{tool_args}, 结果:{tool_result})# 5.将工具调用和结果加入对话历史messages.append({role:assistant,content:[{type:text,text:generated_text}]})# Qwen 格式每个工具调用对应一个 tool 消息fortool_resultintool_results:messages.append({role:tool,name:tool_result[name],content:[{type:text,text:json.dumps(tool_result[result],ensure_asciiFalse)}]})continue# 继续下一轮推理exceptExceptionase:print(f工具调用解析失败{e})# 解析失败时可以选择让模型重新生成或直接返回messages.append({role:assistant,content:[{type:text,text:generated_text}]})messages.append({role:user,content:[{type:text,text:f工具调用解析失败{e}请重新尝试}]})continueelse:print(f最终回复:{generated_text})returngenerated_textreturn达到最大推理轮数query北京现在多少度明天天气怎么样resultreact_inference(query,TOOLS)结果如下[tool_call\nfunctionget_current_temperature\nparameterlocation\n北京, 中国\n/parameter\n/function\n/tool_call\ntool_call\nfunctionget_weather_forecast\nparameterlocation\n北京, 中国\n/parameter\nparameterdate\n2024-01-16\n/parameter\n/function\n/tool_call\n] 调用工具 [get_current_temperature], 参数:{location: 北京, 中国}, 结果:{temperature: 26.5, location: 北京, 中国, unit: celsius} 调用工具 [get_weather_forecast], 参数:{location: 北京, 中国, date: 2024-01-16}, 结果:{forecast: 晴转多云, location: 北京, 中国, date: 2024-01-16} [北京现在温度是 26.5 摄氏度。\n\n明天1月16日北京的天气是晴转多云。\n] 最终回复: 北京现在温度是 26.5 摄氏度。 明天1月16日北京的天气是晴转多云。4 参考资料Qwen3.5: 迈向原生多模态智能体Transformers图像文本转文本ReAct: Synergizing Reasoning and Acting in Language ModelsModelScope千问3.5-2BHuggingFace Qwen3.5-2B