#!/bin/bash # ============================================================ # VetCopilot DAPT v3.1 一键部署脚本 # 适用:GPU 服务器 (A100/RTX 40x0) # ============================================================ set -e echo "============================================" echo " VetCopilot DAPT v3.1 部署" echo " 引擎: Qwen2.5-3B DAPT + LCPS 2.0 + FAISS RAG" echo " $(date)" echo "============================================" # ─── 配置 ─── MODEL_PATH="${VET_MODEL:-./vet-qwen3b-v3-dapt}" PORT_AI="${AI_PORT:-8000}" PORT_APP="${APP_PORT:-8080}" KB_DIR="${KB_DIR:-./knowledge_base_simple}" echo "" echo "[0/4] 检查环境..." python -c "import torch; print(f' CUDA: {torch.cuda.is_available()}'); print(f' GPU: {torch.cuda.get_device_name(0) if torch.cuda.is_available() else \"N/A\"}')" || { echo "[错误] PyTorch CUDA 不可用" exit 1 } # ─── 1. 下载 DAPT 模型(如果不存在)─── echo "" echo "[1/4] 准备 DAPT 模型..." if [ ! -f "$MODEL_PATH/config.json" ]; then echo " 模型不存在,从 ModelScope 下载..." pip install modelscope -q python -c " from modelscope.hub.snapshot_download import snapshot_download snapshot_download('WWSCA123/vet-qwen3b-v3-dapt-inference', local_dir='./vet-qwen3b-v3-dapt') " # 补全 tokenizer(从 HF mirror) python -c " from huggingface_hub import snapshot_download import os, shutil tokenizer_dir = snapshot_download('Qwen/Qwen2.5-3B-Instruct', allow_patterns=['tokenizer*', 'vocab*', 'merges*', 'generation_config*', 'special_tokens*'], local_dir='./_tokenizer_tmp') for f in os.listdir(tokenizer_dir): src = os.path.join(tokenizer_dir, f) dst = os.path.join('$MODEL_PATH', f) if not os.path.exists(dst): shutil.copy(src, dst) rm -rf ./_tokenizer_tmp echo ' 模型准备完成' " else echo " 模型已存在: $MODEL_PATH" fi # ─── 2. 安装依赖 ─── echo "" echo "[2/4] 安装 Python 依赖..." pip install -r vetnetv2.0/requirements_gpu.txt -q 2>/dev/null || { pip install torch transformers accelerate fastapi uvicorn sentence-transformers faiss-gpu -q } pip install -r vetcopilot-backend/requirements.txt -q 2>/dev/null || true echo " 依赖安装完成" # ─── 3. 启动 DAPT 推理服务 ─── echo "" echo "[3/4] 启动 DAPT 推理服务 (端口 $PORT_AI)..." cd vetnetv2.0 nohup python server_gpu.py > ../logs/ai_server.log 2>&1 & AI_PID=$! echo " PID: $AI_PID" # 等待推理服务就绪 echo " 等待推理服务就绪..." for i in $(seq 1 60); do if curl -s http://localhost:$PORT_AI/health | grep -q '"status":"ok"'; then echo " 推理服务就绪" break fi if [ $i -eq 60 ]; then echo " [警告] 推理服务启动超时,检查日志: logs/ai_server.log" fi sleep 5 done cd .. # ─── 4. 启动 VetCopilot 应用 ─── echo "" echo "[4/4] 启动 VetCopilot 应用 (端口 $PORT_APP)..." cd vetcopilot-backend nohup python -m uvicorn app.main:app --host 0.0.0.0 --port $PORT_APP > ../logs/app_server.log 2>&1 & APP_PID=$! echo " PID: $APP_PID" # ─── 完成 ─── echo "" echo "============================================" echo " 部署完成!" echo "" echo " DAPT 推理服务: http://localhost:$PORT_AI" echo " - 健康检查: GET /health" echo " - LCPS 诊断: POST /api/v1/diagnose" echo " - 自由问答: POST /chat" echo "" echo " VetCopilot 应用: http://localhost:$PORT_APP" echo " - 前端: http://localhost:$PORT_APP (Vite dev)" echo " - API: http://localhost:$PORT_APP/api" echo "" echo " 进程 ID:" echo " 推理服务: $AI_PID" echo " 应用服务: $APP_PID" echo "" echo " 停止服务: kill $AI_PID $APP_PID" echo " 查看日志: tail -f logs/ai_server.log" echo " tail -f logs/app_server.log" echo "============================================"