office_gzweb/scripts/install_vlm.sh

302 lines
10 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -euo pipefail
# =============================================================================
# VLM (Qwen2.5-VL-3B) 依赖安装脚本 — 国内镜像优化版
# =============================================================================
# 运行环境ECS GPU 容器(/workspace 挂载在 EFS 上持久化)
# 前置条件NVIDIA GPU 可用CUDA 驱动已安装
#
# 国内镜像策略:
# - pip 包:阿里云镜像
# - HuggingFace 模型hf-mirror.com默认或魔搭 ModelScope
# - PyTorch优先阿里云若缺失则回退官方源
#
# 如需使用官方源(境外环境):
# USE_CHINA_MIRROR=false bash scripts/install_vlm.sh
# =============================================================================
ROOT="/workspace"
SITE_PACKAGES="${ROOT}/.site-packages"
VLM_MODEL_CACHE="${ROOT}/.cache/huggingface"
# 国内镜像开关(默认启用)
USE_CHINA_MIRROR="${USE_CHINA_MIRROR:-true}"
# pip 镜像
PIP_MIRROR_ALIYUN="https://mirrors.aliyun.com/pypi/simple/"
PIP_MIRROR_TSINGHUA="https://pypi.tuna.tsinghua.edu.cn/simple"
PIP_MIRROR_OFFICIAL="https://pypi.org/simple"
# HuggingFace 镜像
HF_MIRROR="https://hf-mirror.com"
# 魔搭 ModelScope阿里云出品国内速度极快
MODELSCOPE_CACHE="${ROOT}/.cache/modelscope"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $*"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
log_error() { echo -e "${RED}[ERROR]${NC} $*"; }
log_step() { echo -e "${BLUE}[STEP]${NC} $*"; }
# -----------------------------------------------------------------------------
# 配置镜像
# -----------------------------------------------------------------------------
if [[ "$USE_CHINA_MIRROR" == "true" ]]; then
log_info "国内镜像模式已启用USE_CHINA_MIRROR=true"
PIP_INDEX="--index-url $PIP_MIRROR_ALIYUN"
HF_ENDPOINT="$HF_MIRROR"
export HF_ENDPOINT
export PIP_INDEX_URL="$PIP_MIRROR_ALIYUN"
# 让 huggingface_hub 使用国内 endpoint
export HF_HUB_ENABLE_HF_TRANSFER=0
else
log_info "官方源模式USE_CHINA_MIRROR=false"
PIP_INDEX=""
HF_ENDPOINT="https://huggingface.co"
fi
# -----------------------------------------------------------------------------
# 0. 环境检查
# -----------------------------------------------------------------------------
log_step "0. 检查 GPU / CUDA 环境..."
if ! command -v nvidia-smi &>/dev/null; then
log_error "nvidia-smi 未找到。请确认当前为 GPU 实例且 NVIDIA 驱动已安装。"
exit 1
fi
nvidia-smi --query-gpu=name,memory.total,driver_version --format=csv,noheader || true
if ! python3 -c "import torch; assert torch.cuda.is_available()" 2>/dev/null; then
log_warn "PyTorch CUDA 未安装或不可用,将重新安装 PyTorch CUDA 版..."
NEED_PYTORCH_CUDA=1
else
python3 -c "import torch; print(f'PyTorch {torch.__version__}, CUDA {torch.version.cuda}, Device: {torch.cuda.get_device_name(0)}')"
NEED_PYTORCH_CUDA=0
fi
# -----------------------------------------------------------------------------
# 1. 安装 PyTorch CUDA (如需要)
# -----------------------------------------------------------------------------
if [[ "$NEED_PYTORCH_CUDA" == "1" ]]; then
log_step "1. 安装 PyTorch 2.1.2 + CUDA 12.1 ..."
if [[ "$USE_CHINA_MIRROR" == "true" ]]; then
# 国内环境:先尝试阿里云 pip 镜像安装 PyTorch
# 注意:阿里云上 PyTorch CUDA wheel 可能滞后,若失败则回退官方源
log_info "尝试从阿里云镜像安装 PyTorch..."
pip install --target="$SITE_PACKAGES" --upgrade \
torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 \
--index-url "$PIP_MIRROR_ALIYUN" \
--no-cache-dir || {
log_warn "阿里云镜像安装 PyTorch 失败,回退到官方源..."
pip install --target="$SITE_PACKAGES" --upgrade \
torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 \
--index-url https://download.pytorch.org/whl/cu121 \
--no-cache-dir
}
else
pip install --target="$SITE_PACKAGES" --upgrade \
torch==2.1.2 torchvision==0.16.2 torchaudio==2.1.2 \
--index-url https://download.pytorch.org/whl/cu121 \
--no-cache-dir
fi
fi
# -----------------------------------------------------------------------------
# 2. 安装 transformers / accelerate / qwen_vl_utils 等
# -----------------------------------------------------------------------------
log_step "2. 安装 Python 依赖包..."
# 先升级 pip 本身(国内镜像)
pip install $PIP_INDEX --upgrade pip setuptools wheel --no-cache-dir || true
pip install --target="$SITE_PACKAGES" $PIP_INDEX --upgrade \
"transformers>=4.40.0" \
"accelerate>=0.30.0" \
"qwen-vl-utils>=0.0.8" \
"pillow>=10.0.0" \
"safetensors>=0.4.0" \
"huggingface-hub>=0.23.0" \
--no-cache-dir
# -----------------------------------------------------------------------------
# 3. 可选:安装 Flash Attention 2 (Ampere+ GPU)
# -----------------------------------------------------------------------------
log_step "3. 检查 GPU 架构..."
GPU_ARCH=$(python3 -c "
import sys, os
sys.path.insert(0, '$SITE_PACKAGES')
import torch
major, minor = torch.cuda.get_device_capability()
print(f'{major}{minor}')
" 2>/dev/null || echo "0")
if [[ "$GPU_ARCH" == "8"* ]] || [[ "$GPU_ARCH" == "9"* ]]; then
log_info "检测到 Ampere/Hopper 架构 (sm_$GPU_ARCH),尝试安装 Flash Attention 2..."
pip install --target="$SITE_PACKAGES" $PIP_INDEX --no-build-isolation \
"flash-attn>=2.5.0" --no-cache-dir || log_warn "Flash Attention 安装失败,将使用 eager attention"
else
log_warn "GPU 架构 sm_$GPU_ARCH 不支持 Flash Attention 2跳过安装"
fi
# -----------------------------------------------------------------------------
# 4. 验证 Python 包
# -----------------------------------------------------------------------------
log_step "4. 验证 Python 包..."
python3 -c "
import sys
sys.path.insert(0, '$SITE_PACKAGES')
import torch
print(f'PyTorch: {torch.__version__}')
print(f'CUDA available: {torch.cuda.is_available()}')
if torch.cuda.is_available():
print(f'Device: {torch.cuda.get_device_name(0)}')
print(f'Memory: {torch.cuda.get_device_properties(0).total_memory / 1e9:.2f} GB')
"
python3 -c "
import sys
sys.path.insert(0, '$SITE_PACKAGES')
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
print('transformers + Qwen2.5-VL classes OK')
"
python3 -c "
import sys
sys.path.insert(0, '$SITE_PACKAGES')
from qwen_vl_utils import process_vision_info
print('qwen_vl_utils OK')
"
# -----------------------------------------------------------------------------
# 5. 预下载模型(国内镜像优先)
# -----------------------------------------------------------------------------
VLM_MODEL="${VLM_MODEL:-Qwen/Qwen2.5-VL-3B-Instruct}"
log_step "5. 预下载 VLM 模型: $VLM_MODEL ..."
mkdir -p "$VLM_MODEL_CACHE"
if [[ "$USE_CHINA_MIRROR" == "true" ]]; then
log_info "尝试通过魔搭 ModelScope 下载模型(国内 fastest..."
# 先安装 modelscope
pip install --target="$SITE_PACKAGES" $PIP_INDEX --upgrade \
"modelscope>=1.15.0" --no-cache-dir
python3 -c "
import sys
sys.path.insert(0, '$SITE_PACKAGES')
from modelscope import snapshot_download
# Qwen 模型在魔搭的命名空间qwen/Qwen2.5-VL-3B-Instruct
model_id = '$VLM_MODEL'
# 如果是 HuggingFace 格式的 model_id转换为魔搭格式
if model_id.startswith('Qwen/'):
modelscope_id = model_id.replace('Qwen/', 'qwen/')
else:
modelscope_id = model_id
print(f'使用魔搭下载: {modelscope_id}')
model_dir = snapshot_download(
modelscope_id,
cache_dir='$MODELSCOPE_CACHE',
)
print(f'模型已下载到: {model_dir}')
# 记录本地模型路径,供 run_all.sh / detector.py 直接使用
path_file = '/workspace/.vlm_model_path'
with open(path_file, 'w') as f:
f.write(f'export VLM_MODEL={model_dir}\\n')
print(f'本地模型路径已记录到: {path_file}')
# 验证可以加载
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
print('验证模型加载...')
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_dir,
torch_dtype='auto',
device_map='auto',
trust_remote_code=True,
)
processor = AutoProcessor.from_pretrained(
model_dir,
trust_remote_code=True,
)
print('模型加载验证成功!')
"
else
log_info "使用 HuggingFace 官方源下载模型..."
export HF_HOME="$VLM_MODEL_CACHE"
python3 -c "
import sys
import os
sys.path.insert(0, '$SITE_PACKAGES')
os.environ['HF_HOME'] = '$VLM_MODEL_CACHE'
from transformers import Qwen2_5_VLForConditionalGeneration, AutoProcessor
from huggingface_hub import snapshot_download
print(f'正在下载模型: $VLM_MODEL ...')
# 先下载到本地缓存
model_dir = snapshot_download(
repo_id='$VLM_MODEL',
cache_dir='$VLM_MODEL_CACHE/hub',
)
print(f'模型已下载到: {model_dir}')
# 记录本地模型路径
path_file = '/workspace/.vlm_model_path'
with open(path_file, 'w') as f:
f.write(f'export VLM_MODEL={model_dir}\\n')
print(f'本地模型路径已记录到: {path_file}')
# 验证加载
model = Qwen2_5_VLForConditionalGeneration.from_pretrained(
model_dir,
torch_dtype='auto',
device_map='auto',
trust_remote_code=True,
)
processor = AutoProcessor.from_pretrained(
model_dir,
trust_remote_code=True,
)
print('模型加载验证成功!')
"
fi
# -----------------------------------------------------------------------------
# 6. 完成
# -----------------------------------------------------------------------------
log_step "6. 安装完成!"
log_info ""
log_info "============================================"
log_info " VLM 安装摘要"
log_info "============================================"
log_info "模型: $VLM_MODEL"
log_info "HF 缓存: $VLM_MODEL_CACHE"
log_info "魔搭缓存: $MODELSCOPE_CACHE"
log_info "Python 包路径: $SITE_PACKAGES"
log_info "国内镜像: $USE_CHINA_MIRROR"
log_info ""
log_info "使用方法:"
log_info " export VISION_BACKEND=vlm"
log_info " export VLM_INTERVAL=5.0"
log_info " ros2 run vision_yolo detector"
log_info ""
log_info "AWQ 量化版(显存 3-4GB:"
log_info " export VLM_MODEL=Qwen/Qwen2.5-VL-3B-Instruct-AWQ"
log_info "============================================"