Qwen2.5-VL-Chord部署教程:Nginx反向代理+HTTPS加密访问企业内网服务
1. 项目简介
1.1 什么是Chord视觉定位服务?
Chord是一个基于Qwen2.5-VL多模态大模型的视觉定位服务。简单来说,它能看懂图片,然后根据你的文字描述,在图片里找到具体的东西。
举个例子,你上传一张客厅的照片,然后输入"找到图里的白色花瓶",Chord就会在图片上画个框,告诉你花瓶在哪个位置。这个功能在很多实际场景中特别有用,比如智能相册管理、工业质检、机器人导航等。
1.2 核心能力亮点
这个服务有几个很实用的特点:
- 自然语言理解:不用学什么专业术语,用大白话描述就能找到目标
- 多目标定位:一次可以找多个东西,比如"找到图中的人和汽车"
- 无需标注数据:直接用现成的模型,不需要自己准备训练数据
- 企业级部署:支持Nginx反向代理和HTTPS加密,适合公司内部使用
- 开箱即用:有Web界面,点点鼠标就能用
1.3 适用场景
这个服务在哪些地方能派上用场呢?
- 电商平台:自动识别商品图片中的关键元素
- 内容审核:快速定位图片中的敏感内容
- 智能安防:在监控视频中定位特定目标
- 工业制造:检测产品缺陷或定位零部件
- 数据标注:辅助人工标注,提高标注效率
2. 部署环境准备
2.1 硬件要求
在开始部署之前,先看看你的服务器够不够用:
| 组件 | 最低要求 | 推荐配置 |
|---|---|---|
| GPU | NVIDIA GPU 8GB显存 | NVIDIA GPU 16GB+显存 |
| 内存 | 16GB RAM | 32GB+ RAM |
| 存储 | 30GB可用空间 | 50GB+可用空间 |
| CPU | 4核 | 8核+ |
重要提示:如果只是测试或者用户量不大,用CPU也能跑,就是速度会慢一些。
2.2 软件环境
需要提前安装好的软件:
# 检查系统版本 cat /etc/os-release # 安装基础依赖 sudo apt-get update sudo apt-get install -y \ nginx \ supervisor \ python3-pip \ python3-venv \ curl \ wget \ git # 安装Docker(可选,用于容器化部署) curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh2.3 网络配置
因为是内网服务,需要确保:
- 防火墙设置:开放必要的端口(7860、443、80)
- 域名准备:准备一个内网域名,比如
chord.internal.company.com - SSL证书:准备HTTPS需要的SSL证书(可以用Let's Encrypt免费申请)
3. Chord服务基础部署
3.1 下载和安装
首先把Chord服务部署起来:
# 创建项目目录 mkdir -p /opt/chord-service cd /opt/chord-service # 克隆项目代码(假设有Git仓库) git clone https://github.com/your-org/chord-service.git . # 或者手动下载 wget https://example.com/chord-service.tar.gz tar -xzf chord-service.tar.gz # 创建Python虚拟环境 python3 -m venv venv source venv/bin/activate # 安装依赖 pip install -r requirements.txt3.2 模型下载和配置
Chord需要Qwen2.5-VL模型文件:
# 创建模型目录 mkdir -p /opt/ai-models/chord # 下载模型文件(根据实际情况调整下载方式) # 方式1:从Hugging Face下载 python -c " from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained('Qwen/Qwen2.5-VL') model.save_pretrained('/opt/ai-models/chord') " # 方式2:如果已经有模型文件,直接复制 cp -r /path/to/your/model/* /opt/ai-models/chord/ # 检查模型文件 ls -lh /opt/ai-models/chord/3.3 基础服务启动
先测试一下基础服务能不能正常运行:
# 激活虚拟环境 source /opt/chord-service/venv/bin/activate # 启动测试服务 cd /opt/chord-service/app python main.py --port 7860 --model-path /opt/ai-models/chord # 在另一个终端测试访问 curl http://localhost:7860如果看到Gradio的界面信息,说明基础服务运行正常。
4. 使用Supervisor管理服务
4.1 Supervisor配置
为了让服务稳定运行,我们用Supervisor来管理:
# 创建Supervisor配置文件 sudo nano /etc/supervisor/conf.d/chord.conf配置文件内容:
[program:chord] command=/opt/chord-service/venv/bin/python /opt/chord-service/app/main.py --port 7860 --model-path /opt/ai-models/chord directory=/opt/chord-service user=www-data autostart=true autorestart=true startsecs=10 startretries=3 stdout_logfile=/var/log/chord/stdout.log stderr_logfile=/var/log/chord/stderr.log environment= PYTHONPATH="/opt/chord-service", MODEL_PATH="/opt/ai-models/chord", DEVICE="cuda"4.2 Supervisor管理命令
# 重新加载配置 sudo supervisorctl reread sudo supervisorctl update # 启动服务 sudo supervisorctl start chord # 查看状态 sudo supervisorctl status chord # 查看日志 sudo tail -f /var/log/chord/stdout.log # 重启服务 sudo supervisorctl restart chord # 停止服务 sudo supervisorctl stop chord4.3 服务自启动
确保Supervisor开机自启:
# 启用Supervisor服务 sudo systemctl enable supervisor sudo systemctl start supervisor # 检查状态 sudo systemctl status supervisor5. Nginx反向代理配置
5.1 为什么需要Nginx?
直接访问7860端口有几个问题:
- 端口不好记
- 没有负载均衡
- 不方便做HTTPS
- 安全性不够
用Nginx反向代理可以解决这些问题。
5.2 基础反向代理配置
创建Nginx配置文件:
sudo nano /etc/nginx/sites-available/chord配置内容:
server { listen 80; server_name chord.internal.company.com; # 访问日志 access_log /var/log/nginx/chord_access.log; error_log /var/log/nginx/chord_error.log; # 反向代理到Chord服务 location / { proxy_pass http://127.0.0.1:7860; # 重要:传递必要的头部信息 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket支持(如果Gradio需要) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 静态文件缓存(如果有的话) location /static/ { alias /opt/chord-service/static/; expires 30d; add_header Cache-Control "public, immutable"; } }5.3 启用配置
# 创建符号链接 sudo ln -s /etc/nginx/sites-available/chord /etc/nginx/sites-enabled/ # 测试配置语法 sudo nginx -t # 重新加载Nginx sudo systemctl reload nginx # 检查Nginx状态 sudo systemctl status nginx5.4 测试访问
现在可以通过域名访问了:
# 测试HTTP访问 curl http://chord.internal.company.com # 或者在浏览器中访问 # http://chord.internal.company.com6. HTTPS加密配置
6.1 SSL证书准备
方案1:使用Let's Encrypt免费证书(推荐)
# 安装Certbot sudo apt-get install -y certbot python3-certbot-nginx # 申请证书(需要域名能公网解析) sudo certbot --nginx -d chord.internal.company.com # 如果是纯内网,需要DNS验证 sudo certbot certonly --manual --preferred-challenges dns -d chord.internal.company.com方案2:使用自签名证书(纯内网)
# 创建证书目录 sudo mkdir -p /etc/nginx/ssl/chord # 生成自签名证书 sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout /etc/nginx/ssl/chord/chord.key \ -out /etc/nginx/ssl/chord/chord.crt \ -subj "/C=CN/ST=Beijing/L=Beijing/O=Company/CN=chord.internal.company.com" # 设置权限 sudo chmod 600 /etc/nginx/ssl/chord/*方案3:使用公司内部CA证书
如果公司有内部的证书颁发机构(CA),可以申请正式的内部证书,这样所有员工电脑都会信任这个证书。
6.2 Nginx HTTPS配置
更新Nginx配置支持HTTPS:
sudo nano /etc/nginx/sites-available/chordHTTPS配置:
# HTTP重定向到HTTPS server { listen 80; server_name chord.internal.company.com; return 301 https://$server_name$request_uri; } # HTTPS主配置 server { listen 443 ssl http2; server_name chord.internal.company.com; # SSL证书配置 ssl_certificate /etc/letsencrypt/live/chord.internal.company.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/chord.internal.company.com/privkey.pem; # 或者使用自签名证书 # ssl_certificate /etc/nginx/ssl/chord/chord.crt; # ssl_certificate_key /etc/nginx/ssl/chord/chord.key; # SSL优化配置 ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512; ssl_prefer_server_ciphers off; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # HSTS头(增强安全) add_header Strict-Transport-Security "max-age=63072000" always; # 访问日志 access_log /var/log/nginx/chord_ssl_access.log; error_log /var/log/nginx/chord_ssl_error.log; # 反向代理配置 location / { proxy_pass http://127.0.0.1:7860; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # WebSocket支持 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # 静态文件 location /static/ { alias /opt/chord-service/static/; expires 30d; add_header Cache-Control "public, immutable"; } # 健康检查端点 location /health { access_log off; return 200 "healthy\n"; add_header Content-Type text/plain; } }6.3 应用配置并测试
# 测试Nginx配置 sudo nginx -t # 重新加载Nginx sudo systemctl reload nginx # 测试HTTPS访问 curl -k https://chord.internal.company.com # 或者用更安全的方式测试 curl --cacert /etc/nginx/ssl/chord/chord.crt https://chord.internal.company.com # 在浏览器中访问 # https://chord.internal.company.com7. 企业级优化配置
7.1 安全加固
防火墙配置
# 只允许内网访问 sudo ufw allow from 10.0.0.0/8 to any port 443 sudo ufw allow from 172.16.0.0/12 to any port 443 sudo ufw allow from 192.168.0.0/16 to any port 443 sudo ufw deny 443 # 或者使用iptables sudo iptables -A INPUT -p tcp --dport 443 -s 10.0.0.0/8 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -s 172.16.0.0/12 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -s 192.168.0.0/16 -j ACCEPT sudo iptables -A INPUT -p tcp --dport 443 -j DROPNginx安全头
在Nginx配置中添加安全头:
# 安全头部配置 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval';" always;访问控制
# 基于IP的访问控制 location / { # 只允许内网IP访问 allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; # 或者基于认证 auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; proxy_pass http://127.0.0.1:7860; }创建密码文件:
# 安装htpasswd工具 sudo apt-get install -y apache2-utils # 创建用户 sudo htpasswd -c /etc/nginx/.htpasswd admin # 添加更多用户 sudo htpasswd /etc/nginx/.htpasswd user17.2 性能优化
Nginx性能调优
# 在http块中添加 http { # 连接优化 keepalive_timeout 65; keepalive_requests 100; # 缓冲区优化 client_body_buffer_size 10K; client_header_buffer_size 1k; client_max_body_size 20M; large_client_header_buffers 2 1k; # 压缩 gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json; } # 在server块中添加 server { # 代理缓冲区 proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; proxy_busy_buffers_size 8k; # 缓存 proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=chord_cache:10m max_size=1g inactive=60m use_temp_path=off; location / { proxy_cache chord_cache; proxy_cache_valid 200 302 10m; proxy_cache_valid 404 1m; proxy_pass http://127.0.0.1:7860; } }Chord服务优化
修改Supervisor配置,增加资源限制:
[program:chord] # ... 其他配置 ... # 资源限制 priority=100 numprocs=1 process_name=%(program_name)s_%(process_num)02d # 内存限制(防止内存泄漏) memory_limit=16GB # 环境优化 environment= OMP_NUM_THREADS=4, MKL_NUM_THREADS=4, PYTHONUNBUFFERED=1, TF_CPP_MIN_LOG_LEVEL=37.3 监控和日志
日志配置
# 配置日志轮转 sudo nano /etc/logrotate.d/chord日志轮转配置:
/var/log/chord/*.log { daily missingok rotate 30 compress delaycompress notifempty create 640 www-data adm sharedscripts postrotate supervisorctl signal chord USR1 endscript }健康检查脚本
创建健康检查脚本:
sudo nano /opt/chord-service/scripts/health_check.sh脚本内容:
#!/bin/bash # 健康检查脚本 SERVICE_URL="https://chord.internal.company.com" HEALTH_CHECK_URL="$SERVICE_URL/health" # 检查服务状态 check_service() { local response=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout 5 "$HEALTH_CHECK_URL") if [ "$response" = "200" ]; then echo "✓ Chord服务运行正常" return 0 else echo "✗ Chord服务异常,HTTP状态码: $response" return 1 fi } # 检查GPU状态 check_gpu() { if command -v nvidia-smi &> /dev/null; then local gpu_usage=$(nvidia-smi --query-gpu=utilization.gpu --format=csv,noheader,nounits | head -1) if [ "$gpu_usage" -gt 95 ]; then echo " GPU使用率过高: ${gpu_usage}%" return 1 else echo "✓ GPU使用率正常: ${gpu_usage}%" return 0 fi else echo "ℹ 未检测到GPU" return 0 fi } # 检查磁盘空间 check_disk() { local disk_usage=$(df /opt | tail -1 | awk '{print $5}' | sed 's/%//') if [ "$disk_usage" -gt 90 ]; then echo " 磁盘空间不足: ${disk_usage}%" return 1 else echo "✓ 磁盘空间充足: ${disk_usage}%" return 0 fi } # 执行所有检查 main() { echo "开始Chord服务健康检查..." echo "================================" local exit_code=0 check_service || exit_code=1 check_gpu || exit_code=1 check_disk || exit_code=1 echo "================================" if [ $exit_code -eq 0 ]; then echo "所有检查通过 ✓" else echo "部分检查未通过 ✗" fi exit $exit_code } main "$@"设置执行权限并添加到定时任务:
# 设置执行权限 chmod +x /opt/chord-service/scripts/health_check.sh # 添加到crontab,每5分钟检查一次 (crontab -l 2>/dev/null; echo "*/5 * * * * /opt/chord-service/scripts/health_check.sh >> /var/log/chord/health_check.log 2>&1") | crontab -8. 多节点负载均衡
8.1 场景分析
如果公司内部使用量大,单个服务器可能不够用,这时候可以考虑部署多个Chord服务节点,用Nginx做负载均衡。
8.2 多节点部署
假设我们在三台服务器上部署Chord服务:
- 节点1: 10.0.1.101:7860
- 节点2: 10.0.1.102:7860
- 节点3: 10.0.1.103:7860
8.3 Nginx负载均衡配置
# 在http块中定义上游服务器 upstream chord_backend { # 负载均衡算法 least_conn; # 最少连接数 # 服务器列表 server 10.0.1.101:7860 max_fails=3 fail_timeout=30s; server 10.0.1.102:7860 max_fails=3 fail_timeout=30s; server 10.0.1.103:7860 max_fails=3 fail_timeout=30s; # 会话保持(如果需要) sticky cookie srv_id expires=1h domain=.internal.company.com path=/; } # HTTPS服务器配置 server { listen 443 ssl http2; server_name chord.internal.company.com; # SSL证书配置... location / { # 代理到上游服务器组 proxy_pass http://chord_backend; # 代理头设置 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # 健康检查 proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504; } # 负载均衡状态页面 location /nginx_status { stub_status on; access_log off; allow 10.0.0.0/8; deny all; } }8.4 会话保持配置
如果应用需要会话保持(比如用户上传图片后的连续操作):
# 基于cookie的会话保持 sticky cookie srv_id expires=1h domain=.internal.company.com path=/; # 或者基于IP的会话保持 ip_hash; # 在location中配置 location / { proxy_pass http://chord_backend; # 传递会话信息 proxy_set_header X-Session-ID $cookie_sessionid; }9. 故障排查和日常维护
9.1 常见问题解决
问题1:HTTPS证书错误
症状:浏览器显示"您的连接不是私密连接"
解决步骤:
# 检查证书有效期 sudo openssl x509 -in /etc/letsencrypt/live/chord.internal.company.com/cert.pem -noout -dates # 续期证书 sudo certbot renew --dry-run sudo certbot renew # 重新加载Nginx sudo systemctl reload nginx问题2:服务响应慢
排查步骤:
# 查看服务器负载 top htop # 查看GPU使用情况 nvidia-smi # 查看Nginx连接数 sudo netstat -anp | grep :443 | wc -l # 查看服务日志 sudo tail -f /var/log/chord/stdout.log sudo tail -f /var/log/nginx/chord_error.log问题3:内存泄漏
症状:服务运行一段时间后内存占用越来越高
解决方案:
# 修改Supervisor配置,定期重启 [program:chord] # 每天凌晨3点重启一次 startsecs=10 stopwaitsecs=300 autorestart=true startretries=3 exitcodes=0,2 stopsignal=TERM或者使用定时任务:
# 每天凌晨重启服务 0 3 * * * supervisorctl restart chord9.2 监控告警设置
使用Prometheus监控
# Nginx Prometheus exporter scrape_configs: - job_name: 'nginx' static_configs: - targets: ['chord.internal.company.com:9113'] metrics_path: /metrics - job_name: 'node' static_configs: - targets: ['10.0.1.101:9100', '10.0.1.102:9100', '10.0.1.103:9100']关键监控指标
- 服务可用性:HTTP状态码、响应时间
- 资源使用:CPU、内存、GPU、磁盘
- 业务指标:请求量、成功率、平均处理时间
9.3 备份和恢复
配置文件备份
# 创建备份脚本 sudo nano /opt/chord-service/scripts/backup.sh备份脚本内容:
#!/bin/bash BACKUP_DIR="/backup/chord-service" DATE=$(date +%Y%m%d_%H%M%S) # 创建备份目录 mkdir -p "$BACKUP_DIR/$DATE" # 备份配置文件 cp -r /etc/nginx/sites-available/chord "$BACKUP_DIR/$DATE/" cp -r /etc/supervisor/conf.d/chord.conf "$BACKUP_DIR/$DATE/" cp -r /opt/chord-service/config/ "$BACKUP_DIR/$DATE/" # 备份模型文件(如果模型有更新) # cp -r /opt/ai-models/chord/ "$BACKUP_DIR/$DATE/model/" # 备份数据库(如果有) # pg_dump chord_db > "$BACKUP_DIR/$DATE/chord_db.sql" # 压缩备份 tar -czf "$BACKUP_DIR/chord_backup_$DATE.tar.gz" -C "$BACKUP_DIR/$DATE" . # 清理旧备份(保留最近7天) find "$BACKUP_DIR" -name "*.tar.gz" -mtime +7 -delete echo "备份完成: $BACKUP_DIR/chord_backup_$DATE.tar.gz"恢复流程
# 停止服务 sudo supervisorctl stop chord sudo systemctl stop nginx # 恢复配置文件 tar -xzf chord_backup_20240101_120000.tar.gz cp -r config/* /opt/chord-service/config/ cp chord.conf /etc/supervisor/conf.d/ cp chord /etc/nginx/sites-available/ # 重新加载配置 sudo supervisorctl reread sudo supervisorctl update sudo nginx -t sudo systemctl reload nginx # 启动服务 sudo supervisorctl start chord10. 总结
10.1 部署要点回顾
通过这个教程,我们完成了Chord视觉定位服务的企业级部署,主要包含:
- 基础服务部署:安装Chord服务,配置Supervisor管理
- Nginx反向代理:通过域名访问,隐藏后端端口
- HTTPS加密:使用SSL证书保证数据传输安全
- 安全加固:配置防火墙、访问控制、安全头部
- 性能优化:调优Nginx和Chord服务参数
- 负载均衡:支持多节点部署,提高可用性
- 监控维护:配置健康检查、日志管理、备份恢复
10.2 实际使用建议
根据不同的使用场景,可以选择不同的部署方案:
- 小团队测试:单节点 + HTTP访问即可
- 部门级使用:单节点 + HTTPS + 基础安全配置
- 企业级应用:多节点负载均衡 + 完整监控体系
10.3 后续优化方向
如果使用过程中发现性能瓶颈,可以考虑:
- 模型优化:使用量化后的模型,减少显存占用
- 缓存策略:对常用图片和结果进行缓存
- 异步处理:对于大量图片处理,使用消息队列
- 容器化部署:使用Docker或Kubernetes,便于扩展和管理
10.4 快速检查清单
部署完成后,可以用这个清单检查是否一切正常:
# 1. 检查服务状态 sudo supervisorctl status chord # 2. 检查Nginx配置 sudo nginx -t # 3. 测试HTTPS访问 curl -I https://chord.internal.company.com # 4. 检查证书有效期 sudo openssl x509 -in /etc/letsencrypt/live/chord.internal.company.com/cert.pem -noout -dates # 5. 检查防火墙规则 sudo ufw status verbose # 6. 运行健康检查 /opt/chord-service/scripts/health_check.sh记住,企业级部署的核心是"稳定、安全、可维护"。按照这个教程部署的Chord服务,应该能够满足大多数企业的内部使用需求。如果在使用过程中遇到问题,先检查日志,大多数问题都能在日志中找到答案。
获取更多AI镜像
想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。