个人备案 网站名称 例子上海企业服务云平台
个人备案 网站名称 例子,上海企业服务云平台,哪里有网页设计培训,佛山从事网站建设Qwen3.5-35B-A3B-AWQ-4bit部署全流程代码实例#xff1a;supervisor配置端口检查脚本
1. 引言#xff1a;为什么需要完整的部署方案#xff1f;
如果你正在寻找一个能看懂图片、能回答图片相关问题的AI模型#xff0c;Qwen3.5-35B-A3B-AWQ-4bit可能就是你需要的那个。这个…Qwen3.5-35B-A3B-AWQ-4bit部署全流程代码实例supervisor配置端口检查脚本1. 引言为什么需要完整的部署方案如果你正在寻找一个能看懂图片、能回答图片相关问题的AI模型Qwen3.5-35B-A3B-AWQ-4bit可能就是你需要的那个。这个模型专门为视觉理解设计你上传一张照片它就能告诉你照片里有什么、发生了什么甚至能回答你关于图片的各种问题。听起来很酷对吧但真正用起来的时候很多人会卡在部署这一步。模型文件下载好了代码也准备好了可服务就是起不来或者运行一会儿就崩溃了。更头疼的是出了问题不知道怎么查重启服务还得记一堆命令。今天我要分享的就是一套完整的部署方案。不只是把模型跑起来而是让它稳定、可靠地运行并且方便管理。我会带你一步步配置supervisor来管理服务进程再写一个实用的端口检查脚本让你随时知道服务状态。这样部署完成后你就能专注于使用模型的能力而不是整天折腾环境。2. 环境准备与模型理解2.1 你需要准备什么在开始之前我们先看看需要哪些东西。别担心大部分都是现成的你只需要确认一下硬件要求至少两张24GB显存的GPU卡。这个模型即使经过4bit量化单卡24GB还是不太稳定双卡是经过验证的可靠方案。系统环境Linux系统建议Ubuntu 20.04或更高版本。基础软件Python 3.8pip还有基本的编译工具。模型文件Qwen3.5-35B-A3B-AWQ-4bit的量化模型文件。如果你在CSDN星图平台上部署这些环境通常都已经准备好了。如果是自己的服务器可能需要多花点时间配置。2.2 这个模型能做什么简单来说这是一个能看图的聊天机器人。你给它一张图片它就能描述图片内容告诉你图片里有什么人、物、场景回答图片相关问题比如图片里的人在做什么、这个产品的价格是多少识别文字图片中的文字内容也能提取出来多轮对话围绕同一张图片可以连续问多个问题特别适合用在电商商品分析、内容审核、教育辅导这些需要理解图片内容的场景。2.3 技术路线选择这里有个重要的技术细节需要了解。这个模型是pack-quantized格式的如果用原生的Transformers直接加载在当前环境下可能会出现量化权重接管不完整的问题最终导致内存溢出OOM。经过测试稳定的方案是使用vLLM compressed-tensors这个组合。vLLM负责高效的推理服务compressed-tensors专门处理压缩后的张量。这个组合已经被验证过能稳定运行这个量化模型。3. 完整部署步骤3.1 第一步下载和准备模型首先我们需要把模型文件放到合适的位置。假设你的工作目录是/root/workspace# 创建工作目录 mkdir -p /root/workspace/qwen35awq cd /root/workspace/qwen35awq # 这里假设你已经有了模型文件 # 如果没有需要从合适的源下载 # 模型文件应该包含类似这样的结构 # qwen35awq/ # ├── config.json # ├── model.safetensors # └── 其他必要的文件确保模型文件的权限正确chmod -R 755 /root/workspace/qwen35awq3.2 第二步安装依赖包我们需要安装一些必要的Python包。创建一个requirements.txt文件vllm0.4.2 compressed-tensors0.2.2 fastapi0.104.1 uvicorn0.24.0 gradio4.19.2 pillow10.1.0 torch2.1.0然后安装它们pip install -r requirements.txt如果你在国内可能需要配置镜像源来加速下载pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple3.3 第三步编写后端服务代码创建一个后端服务文件backend.pyfrom vllm import AsyncLLMEngine, SamplingParams from vllm.engine.arg_utils import AsyncEngineArgs from compressed_tensors import load_compressed_model import asyncio from fastapi import FastAPI, UploadFile, File, Form from fastapi.responses import JSONResponse import base64 from PIL import Image import io import json app FastAPI() # 初始化模型引擎 engine_args AsyncEngineArgs( model/root/workspace/qwen35awq, tensor_parallel_size2, # 使用双卡 max_model_len4096, # 上下文长度 enforce_eagerTrue, # 关闭cudagraph走eager模式 dtypefloat16, # 推理精度 gpu_memory_utilization0.9 ) # 加载压缩模型 print(正在加载模型...) model load_compressed_model(engine_args.model) engine AsyncLLMEngine.from_engine_args(engine_args, modelmodel) print(模型加载完成) app.post(/analyze) async def analyze_image( image: UploadFile File(...), question: str Form(...) ): 分析图片并回答问题 # 读取图片 image_data await image.read() image_pil Image.open(io.BytesIO(image_data)) # 将图片转换为base64 buffered io.BytesIO() image_pil.save(buffered, formatJPEG) img_str base64.b64encode(buffered.getvalue()).decode() # 构建提示词 prompt f|im_start|user\n图片内容[图片数据{img_str}]\n问题{question}|im_end|\n|im_start|assistant\n # 设置采样参数 sampling_params SamplingParams( temperature0.7, top_p0.9, max_tokens512 ) # 生成回答 results_generator engine.generate(prompt, sampling_params, request_idtest) async for request_output in results_generator: response request_output.outputs[0].text return JSONResponse({ status: success, answer: response, question: question }) app.get(/health) async def health_check(): 健康检查接口 return {status: healthy, model: Qwen3.5-35B-A3B-AWQ-4bit} if __name__ __main__: import uvicorn uvicorn.run(app, host0.0.0.0, port8000)3.4 第四步编写前端Web界面创建一个前端文件web_ui.pyimport gradio as gr import requests import tempfile from PIL import Image import io # 后端API地址 BACKEND_URL http://127.0.0.1:8000 def analyze_image_with_question(image, question, history): 调用后端API分析图片 if image is None: return 请先上传图片, history if not question.strip(): return 请输入问题, history try: # 保存图片到临时文件 with tempfile.NamedTemporaryFile(suffix.jpg, deleteFalse) as tmp: image.save(tmp.name, formatJPEG) # 调用后端API with open(tmp.name, rb) as img_file: files {image: img_file} data {question: question} response requests.post( f{BACKEND_URL}/analyze, filesfiles, datadata, timeout300 ) if response.status_code 200: result response.json() answer result[answer] # 更新对话历史 new_history history [(question, answer)] return answer, new_history else: return f请求失败: {response.status_code}, history except Exception as e: return f处理出错: {str(e)}, history def clear_conversation(): 清空对话 return None, [], # 创建Gradio界面 with gr.Blocks(titleQwen3.5 图文对话系统, themegr.themes.Soft()) as demo: gr.Markdown(# ️ Qwen3.5-35B-A3B-AWQ-4bit 图文对话系统) gr.Markdown(上传图片然后提问关于图片的任何问题) with gr.Row(): with gr.Column(scale1): image_input gr.Image( label上传图片, typepil, height400 ) question_input gr.Textbox( label输入问题, placeholder例如描述图片内容、图片里有什么、文字是什么..., lines3 ) with gr.Row(): submit_btn gr.Button(发送问题, variantprimary) clear_btn gr.Button(清空对话, variantsecondary) with gr.Column(scale2): chatbot gr.Chatbot( label对话记录, height500, bubble_full_widthFalse ) # 绑定事件 submit_btn.click( analyze_image_with_question, inputs[image_input, question_input, chatbot], outputs[question_input, chatbot] ) clear_btn.click( clear_conversation, outputs[image_input, chatbot, question_input] ) # 示例 gr.Examples( examples[ [描述这张图片的内容, 图片里有什么], [图片中的文字是什么, 读取图片中的文字], [这个人在做什么, 分析人物动作] ], inputs[question_input], label试试这些问题 ) if __name__ __main__: demo.launch( server_name0.0.0.0, server_port7860, shareFalse )4. Supervisor配置让服务稳定运行4.1 为什么需要Supervisor你可能遇到过这种情况服务运行得好好的突然就挂了或者服务器重启后所有服务都要手动启动。Supervisor就是来解决这些问题的。Supervisor是一个进程管理工具它能自动启动服务服务崩溃时自动重启方便地查看服务状态和日志统一管理多个服务4.2 安装Supervisor如果你的系统还没有安装Supervisor# Ubuntu/Debian apt-get update apt-get install -y supervisor # CentOS/RHEL yum install -y supervisor # 启动Supervisor服务 systemctl enable supervisor systemctl start supervisor4.3 配置后端服务创建后端服务的配置文件/etc/supervisor/conf.d/qwen35awq-backend.conf[program:qwen35awq-backend] command/usr/bin/python3 /root/workspace/backend.py directory/root/workspace userroot autostarttrue autorestarttrue startsecs10 startretries3 stdout_logfile/root/workspace/qwen35awq-backend.log stdout_logfile_maxbytes50MB stdout_logfile_backups10 stderr_logfile/root/workspace/qwen35awq-backend-error.log stderr_logfile_maxbytes50MB stderr_logfile_backups10 environmentPYTHONPATH/root/workspace,PATH/usr/bin:/bin这个配置的意思是command启动命令用Python运行我们的后端代码directory工作目录autostarttrueSupervisor启动时自动启动这个服务autorestarttrue服务崩溃时自动重启stdout_logfile标准输出日志文件位置stderr_logfile错误日志文件位置4.4 配置前端Web服务创建前端服务的配置文件/etc/supervisor/conf.d/qwen35awq-web.conf[program:qwen35awq-web] command/usr/bin/python3 /root/workspace/web_ui.py directory/root/workspace userroot autostarttrue autorestarttrue startsecs10 startretries3 stdout_logfile/root/workspace/qwen35awq-web.log stdout_logfile_maxbytes50MB stdout_logfile_backups10 stderr_logfile/root/workspace/qwen35awq-web-error.log stderr_logfile_maxbytes50MB stderr_logfile_backups10 environmentPYTHONPATH/root/workspace,PATH/usr/bin:/bin4.5 加载和启动服务配置完成后需要让Supervisor重新加载配置# 重新加载配置文件 supervisorctl reread # 更新配置会重启有变化的服务 supervisorctl update # 启动所有服务 supervisorctl start all # 查看服务状态 supervisorctl status如果一切正常你应该能看到类似这样的输出qwen35awq-backend RUNNING pid 12345, uptime 0:00:30 qwen35awq-web RUNNING pid 12346, uptime 0:00:305. 端口检查脚本随时掌握服务状态5.1 为什么需要端口检查服务部署好了但你怎么知道它真的在运行端口检查脚本就像是一个健康检查员它能告诉你服务端口是否正常监听服务是否能够响应请求哪个服务可能出了问题5.2 编写端口检查脚本创建一个检查脚本check_ports.sh#!/bin/bash # 端口检查脚本 # 检查Qwen3.5相关服务的端口状态 echo Qwen3.5服务状态检查 echo echo 检查时间: $(date) echo # 定义要检查的端口 declare -A SERVICES SERVICES[8000]后端API服务 (qwen35awq-backend) SERVICES[7860]前端Web服务 (qwen35awq-web) # 检查Supervisor服务状态 echo 1. Supervisor服务状态: echo ---------------------- supervisorctl status | grep qwen35awq echo # 检查端口监听状态 echo 2. 端口监听状态: echo ---------------- for PORT in ${!SERVICES[]}; do SERVICE_NAME${SERVICES[$PORT]} # 检查端口是否被监听 if ss -ltnp | grep -q :${PORT} ; then PID$(ss -ltnp | grep :${PORT} | awk {print $6} | cut -d -f2 | cut -d, -f1) PROCESS$(ps -p $PID -o comm 2/dev/null || echo 未知进程) echo ✅ 端口 ${PORT} (${SERVICE_NAME}) echo 状态: 正在监听 echo 进程ID: ${PID} echo 进程名: ${PROCESS} else echo ❌ 端口 ${PORT} (${SERVICE_NAME}) echo 状态: 未监听 fi echo done # 检查服务健康状态 echo 3. 服务健康检查: echo ---------------- # 检查后端API健康 echo 后端API健康检查: if curl -s http://127.0.0.1:8000/health /dev/null; then RESPONSE$(curl -s http://127.0.0.1:8000/health) STATUS$(echo $RESPONSE | python3 -c import sys, json; print(json.load(sys.stdin)[status])) echo ✅ 健康状态: ${STATUS} else echo ❌ 无法连接到后端API fi echo # 检查前端Web服务 echo 前端Web服务检查: if curl -s http://127.0.0.1:7860 /dev/null; then echo ✅ Web界面可访问 else echo ❌ Web界面无法访问 fi echo # 检查GPU使用情况 echo 4. GPU使用情况: echo ---------------- if command -v nvidia-smi /dev/null; then nvidia-smi --query-gpuname,utilization.gpu,memory.used,memory.total --formatcsv,noheader else echo ℹ️ nvidia-smi未找到跳过GPU检查 fi echo # 检查日志文件大小 echo 5. 日志文件状态: echo ---------------- LOG_FILES( /root/workspace/qwen35awq-backend.log /root/workspace/qwen35awq-backend-error.log /root/workspace/qwen35awq-web.log /root/workspace/qwen35awq-web-error.log ) for LOG_FILE in ${LOG_FILES[]}; do if [ -f $LOG_FILE ]; then SIZE$(du -h $LOG_FILE | cut -f1) LINES$(wc -l $LOG_FILE) echo $(basename $LOG_FILE): ${SIZE}, ${LINES}行 else echo ⚠️ $(basename $LOG_FILE): 文件不存在 fi done echo echo echo 检查完成!给脚本添加执行权限chmod x check_ports.sh5.3 使用检查脚本现在你可以随时运行这个脚本来检查服务状态# 直接运行 ./check_ports.sh # 或者添加到crontab定期检查 # 每5分钟检查一次 */5 * * * * /root/workspace/check_ports.sh /root/workspace/service_monitor.log 21脚本运行后会显示Supervisor中服务的运行状态端口8000和7860是否被监听服务健康检查结果GPU使用情况日志文件状态5.4 常见问题自动诊断我们还可以增强脚本让它能自动诊断一些常见问题#!/bin/bash # 增强版自动诊断问题 diagnose_problem() { echo 开始自动诊断... echo # 检查1: 端口是否被占用 echo 检查1: 端口占用情况 for PORT in 8000 7860; do CONFLICT_PID$(lsof -ti:${PORT}) if [ ! -z $CONFLICT_PID ]; then CONFLICT_CMD$(ps -p $CONFLICT_PID -o cmd) echo ⚠️ 端口 ${PORT} 被其他进程占用: echo 进程ID: ${CONFLICT_PID} echo 命令: ${CONFLICT_CMD} echo 建议: sudo kill -9 ${CONFLICT_PID} 然后重启服务 fi done echo # 检查2: 模型文件是否存在 echo 检查2: 模型文件 MODEL_DIR/root/workspace/qwen35awq if [ -d $MODEL_DIR ]; then FILE_COUNT$(find $MODEL_DIR -type f -name *.safetensors | wc -l) if [ $FILE_COUNT -gt 0 ]; then echo ✅ 模型目录存在找到 ${FILE_COUNT} 个模型文件 else echo ❌ 模型目录存在但未找到.safetensors文件 fi else echo ❌ 模型目录不存在: ${MODEL_DIR} fi echo # 检查3: 依赖包 echo 检查3: Python依赖包 REQUIRED_PACKAGES(vllm compressed-tensors fastapi gradio) for PKG in ${REQUIRED_PACKAGES[]}; do if python3 -c import $PKG 2/dev/null; then VERSION$(python3 -c import $PKG; print($PKG.__version__) 2/dev/null || echo 未知版本) echo ✅ ${PKG}: ${VERSION} else echo ❌ ${PKG}: 未安装 fi done echo # 检查4: GPU内存 echo 检查4: GPU内存 if command -v nvidia-smi /dev/null; then GPU_MEMORY$(nvidia-smi --query-gpumemory.used,memory.total --formatcsv,noheader,nounits) echo GPU内存使用: ${GPU_MEMORY} # 检查是否有足够内存 while IFS, read USED TOTAL; do if [ $USED -gt $((TOTAL * 90 / 100)) ]; then echo ⚠️ GPU内存使用率超过90%可能影响模型加载 fi done $GPU_MEMORY fi echo } # 在检查脚本中加入诊断功能 echo 是否运行自动诊断(y/n) read -r RUN_DIAGNOSE if [[ $RUN_DIAGNOSE ~ ^[Yy]$ ]]; then diagnose_problem fi6. 服务管理命令汇总部署完成后这些命令会经常用到我把它们整理在一起方便你查找6.1 服务状态管理# 查看所有服务状态 supervisorctl status # 查看特定服务状态 supervisorctl status qwen35awq-backend supervisorctl status qwen35awq-web # 重启服务 supervisorctl restart qwen35awq-backend supervisorctl restart qwen35awq-web # 重启所有服务 supervisorctl restart all # 停止服务 supervisorctl stop qwen35awq-backend # 启动服务 supervisorctl start qwen35awq-backend # 重新加载配置修改配置文件后 supervisorctl reread supervisorctl update6.2 日志查看# 查看后端服务日志最后100行 tail -100 /root/workspace/qwen35awq-backend.log # 实时查看日志 tail -f /root/workspace/qwen35awq-backend.log # 查看错误日志 tail -100 /root/workspace/qwen35awq-backend-error.log # 查看前端服务日志 tail -100 /root/workspace/qwen35awq-web.log # 查看Supervisor主日志 tail -100 /var/log/supervisor/supervisord.log6.3 端口和进程检查# 检查端口监听状态 ss -ltnp | grep -E 7860|8000 # 检查特定端口 lsof -i:7860 lsof -i:8000 # 检查进程 ps aux | grep qwen35awq # 检查GPU使用 nvidia-smi # 运行我们的检查脚本 ./check_ports.sh6.4 服务访问# 本地访问如果服务运行在同一台机器 curl http://127.0.0.1:8000/health # 通过SSH隧道访问从本地机器 ssh -L 7860:127.0.0.1:7860 -p 你的端口 root你的服务器IP # 然后在本地浏览器打开 # http://127.0.0.1:78607. 常见问题与解决方案7.1 服务启动失败问题运行supervisorctl status看到服务是FATAL或BACKOFF状态。解决步骤查看错误日志tail -100 /root/workspace/qwen35awq-backend-error.log常见错误及解决端口被占用Address already in use# 查找占用端口的进程 lsof -i:8000 lsof -i:7860 # 停止冲突进程或修改服务端口模型文件不存在No such file or directory# 检查模型路径 ls -la /root/workspace/qwen35awq/ # 确保模型文件存在且可读GPU内存不足CUDA out of memory# 检查GPU内存 nvidia-smi # 尝试减少tensor_parallel_size # 修改backend.py中的tensor_parallel_size17.2 Web界面能打开但无法回答问题问题能上传图片但点击发送后长时间无响应或报错。解决步骤检查后端服务是否正常curl http://127.0.0.1:8000/health检查后端日志tail -f /root/workspace/qwen35awq-backend.log常见原因图片太大模型处理大图片需要更多时间问题太复杂复杂推理问题需要更长时间首次请求预热第一次请求会加载模型需要耐心等待7.3 服务运行一段时间后崩溃问题服务刚开始正常但运行一段时间后自动停止。解决检查系统资源# 查看内存使用 free -h # 查看GPU内存 nvidia-smi调整Supervisor配置增加重启次数# 在配置文件中增加 startretries10 # 增加重试次数 stopwaitsecs30 # 增加停止等待时间检查是否有内存泄漏# 监控内存增长 watch -n 5 ps aux | grep qwen35awq7.4 性能优化建议如果觉得服务响应慢可以尝试调整图片大小在前端代码中压缩图片# 在web_ui.py的analyze_image_with_question函数中添加 image image.resize((1024, 1024)) # 调整到合适大小启用缓存对相同图片的问题进行缓存批量处理如果需要处理大量图片考虑批量处理接口监控优化使用我们的检查脚本定期监控及时发现性能瓶颈8. 总结通过这套完整的部署方案你现在应该已经拥有了一个稳定运行的Qwen3.5-35B-A3B-AWQ-4bit图文对话服务。让我们回顾一下关键点部署的核心价值不只是让服务跑起来而是让它稳定运行通过Supervisor确保服务异常时自动恢复易于监控通过检查脚本随时了解服务状态方便管理统一的服务管理命令和日志查看方式快速排错清晰的错误日志和诊断工具这套方案的优点一键部署按照步骤操作不需要深入每个技术细节自动恢复服务崩溃会自动重启减少人工干预状态透明随时知道服务是否健康哪里可能有问题易于扩展如果需要增加更多服务同样的模式可以复用实际使用建议首次部署后先运行检查脚本确认一切正常定期查看日志文件了解服务运行状况使用Supervisor命令管理服务不要直接kill进程遇到问题时先看日志再用检查脚本诊断现在你的图文对话AI服务已经准备就绪。你可以开始上传图片问它各种问题看看这个多模态模型能给你带来什么惊喜。无论是分析商品图片、理解图表内容还是简单的看图说话它都能给你不错的回答。记住技术部署只是第一步真正的价值在于如何把这个能力用到你的实际业务中。祝你在AI探索的路上越走越远获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。