Skip to content

开源模型端到端部署指南

将开源大模型从 Hugging Face Hub 部署到生产环境,需要经过下载、量化、Serving 和监控四个关键环节。本指南提供每一步的实操路径。

概述

开源模型部署的核心挑战:

  • 显存限制:大模型参数动辄数十 GB,需要量化或分布式策略
  • 吞吐优化:单用户延迟 vs 多用户并发,需要 Continuous Batching
  • 服务稳定性:模型加载慢、推理易 OOM,需要完善的监控和降级
  • 多模型管理:不同任务需要不同模型,需要统一路由和调度

本指南覆盖从单卡本地部署到 Kubernetes 集群的完整路径。


1. 模型下载与加载

1.1 从 Hugging Face Hub 下载

命令行工具

bash
# 安装
pip install huggingface-hub

# 下载整个模型仓库
huggingface-cli download meta-llama/Llama-2-7b-hf \
  --local-dir ./models/llama2-7b \
  --local-dir-use-symlinks False

# 只下载特定文件
huggingface-cli download meta-llama/Llama-2-7b-hf \
  model.safetensors.index.json \
  --local-dir ./models/llama2-7b

Python API

python
from huggingface_hub import snapshot_download

snapshot_download(
    repo_id="meta-llama/Llama-2-7b-hf",
    local_dir="./models/llama2-7b",
    local_dir_use_symlinks=False,
    resume_download=True,  # 断点续传
)

1.2 离线环境部署

bash
# 有网络环境:预下载到本地
export HF_DATASETS_OFFLINE=1
export TRANSFORMERS_OFFLINE=1

# 代码中强制本地加载
model = AutoModelForCausalLM.from_pretrained(
    "./models/llama2-7b",
    local_files_only=True,
)

1.3 私有模型与认证

bash
# 登录 Hugging Face
huggingface-cli login

# 或使用 Access Token
export HF_TOKEN=hf_xxx

2. 模型量化

量化是将模型权重从高精度(FP32/FP16)转换为低精度(INT8/INT4),显著减少显存占用。

2.1 量化方案对比

方案精度显存节省速度影响适用场景
FP16/BF1616-bit基准基准通用
GPTQ4-bit~75%-10~20%GPU 推理
AWQ4-bit~75%优于 GPTQGPU 推理
GGUF2-8-bit50-87%CPU 友好边缘/CPU
BNF (bitsandbytes)8/4-bit~50-75%-10%训练+推理

2.2 GPTQ 量化

python
from transformers import AutoModelForCausalLM, GPTQConfig

# 配置 GPTQ 量化
quantization_config = GPTQConfig(
    bits=4,
    group_size=128,
    desc_act=False,  # 是否按激活顺序排列
    dataset="c4",    # 校准数据集
)

# 量化并保存
model = AutoModelForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    quantization_config=quantization_config,
    device_map="auto",
)
model.save_pretrained("./models/llama2-7b-gptq")

2.3 AWQ 量化

bash
# 安装 AutoAWQ
pip install autoawq

# 量化
from awq import AutoAWQForCausalLM

model = AutoAWQForCausalLM.from_pretrained(
    "meta-llama/Llama-2-7b-hf",
    use_cache=False,
)
model.quantize(
    tokenizer=tokenizer,
    quant_config={"zero_point": True, "q_group_size": 128, "w_bit": 4}
)
model.save_quantized("./models/llama2-7b-awq")

2.4 GGUF 转换(用于 llama.cpp)

bash
# 克隆 llama.cpp
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp

# 转换 Hugging Face 模型为 GGUF
python convert_hf_to_gguf.py \
  ../models/llama2-7b \
  --outfile ../models/llama2-7b-f16.gguf \
  --outtype f16

# 量化 GGUF(Q4_K_M 推荐)
./llama-quantize \
  ../models/llama2-7b-f16.gguf \
  ../models/llama2-7b-q4_k_m.gguf \
  Q4_K_M

GGUF 量化类型选择

类型大小质量推荐场景
Q4_0最小一般极速推理
Q4_K_M推荐通用
Q5_K_M中等很好质量优先
Q8_0较大接近无损高精度需求

3. Serving 方案

3.1 方案选择决策树

有 GPU?
├── 是 → 需要高吞吐?
│   ├── 是 → vLLM / TGI
│   └── 否 → Ollama / Transformers
└── 否 → 边缘/CPU 部署?
    ├── 是 → llama.cpp
    └── 否 → Ollama (CPU 模式)

3.2 vLLM(高吞吐 GPU 推理)

vLLM 基于 PagedAttention 算法,通过非连续 KV Cache 管理实现高吞吐推理。

安装与启动

bash
# 安装
pip install vllm

# 启动 OpenAI-compatible API 服务
python -m vllm.entrypoints.openai.api_server \
  --model meta-llama/Llama-2-7b-hf \
  --tensor-parallel-size 1 \
  --dtype bfloat16 \
  --max-model-len 4096 \
  --port 8000

Docker 部署

bash
docker run --runtime nvidia --gpus all \
  -v ~/.cache/huggingface:/root/.cache/huggingface \
  -p 8000:8000 \
  vllm/vllm-openai:latest \
  --model meta-llama/Llama-2-7b-hf

调用示例

python
from openai import OpenAI

client = OpenAI(base_url="http://localhost:8000/v1", api_key="dummy")

response = client.chat.completions.create(
    model="meta-llama/Llama-2-7b-hf",
    messages=[{"role": "user", "content": "你好"}],
    temperature=0.7,
)
print(response.choices[0].message.content)

关键参数

参数说明建议
--tensor-parallel-sizeGPU 数量单卡=1,多卡=N
--max-model-len最大序列长度根据模型和显存调整
--dtype数据类型bfloat16 / float16
--quantization量化方式awq / gptq / fp8
--gpu-memory-utilizationGPU 显存利用率0.9(留余量)

3.3 llama.cpp(边缘/CPU 推理)

纯 C/C++ 实现,零依赖,支持多平台。

编译

bash
cd llama.cpp

# CPU 版本
make

# CUDA 版本
make LLAMA_CUDA=1

# Metal (Apple Silicon)
make LLAMA_METAL=1

启动 Server

bash
./server \
  -m ../models/llama2-7b-q4_k_m.gguf \
  -c 4096 \
  --host 0.0.0.0 \
  --port 8080 \
  -ngl 35  # GPU 层数(Metal/CUDA)

Python 绑定

python
from llama_cpp import Llama

llm = Llama(
    model_path="./models/llama2-7b-q4_k_m.gguf",
    n_ctx=4096,
    n_gpu_layers=35,  # offload 到 GPU 的层数
)

output = llm(
    "Q: 什么是量子计算?\nA: ",
    max_tokens=256,
    temperature=0.7,
)
print(output["choices"][0]["text"])

3.4 TGI(Hugging Face 官方)

bash
# Docker 启动
docker run --gpus all --shm-size 1g -p 8080:80 \
  -v ~/.cache/huggingface:/data \
  ghcr.io/huggingface/text-generation-inference:latest \
  --model-id meta-llama/Llama-2-7b-hf \
  --quantize gptq

3.5 Ollama(一键本地运行)

bash
# 安装
curl -fsSL https://ollama.com/install.sh | sh

# 运行模型
ollama run llama3

# 导入自定义模型(GGUF)
# 创建 Modelfile
 cat > Modelfile <<EOF
FROM ./models/llama2-7b-q4_k_m.gguf
PARAMETER temperature 0.7
PARAMETER num_ctx 4096
SYSTEM 你是一位专业的技术助手
EOF

ollama create my-model -f Modelfile
ollama run my-model

4. 监控与运维

4.1 关键监控指标

指标说明告警阈值
TTFT (Time To First Token)首 token 延迟> 2s
TPOT (Time Per Output Token)每 token 生成时间> 100ms
Throughput每秒生成 token 数低于基线 20%
Queue Length等待队列长度> 10
GPU MemoryGPU 显存使用率> 90%
KV Cache UsageKV Cache 使用率> 95%
Error Rate请求错误率> 1%

4.2 vLLM 监控

vLLM 内置 Prometheus metrics:

bash
# Metrics 端点
curl http://localhost:8000/metrics

# 关键指标
vllm:time_to_first_token_seconds
vllm:time_per_output_token_seconds
vllm:e2e_request_latency_seconds
vllm:request_queue_time_seconds
vllm:gpu_cache_usage_perc
vllm:num_requests_running
vllm:num_requests_waiting

Grafana Dashboard 配置

yaml
# docker-compose.yml
services:
  prometheus:
    image: prom/prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    ports:
      - "9090:9090"
  
  grafana:
    image: grafana/grafana
    ports:
      - "3000:3000"

4.3 日志与追踪

python
# OpenTelemetry 集成
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter

tracer = trace.get_tracer(__name__)

with tracer.start_as_current_span("llm-inference") as span:
    span.set_attribute("model", "llama2-7b")
    span.set_attribute("input_tokens", len(input_ids))
    
    output = model.generate(input_ids)
    
    span.set_attribute("output_tokens", len(output))
    span.set_attribute("latency_ms", latency)

5. 负载均衡与扩缩容

5.1 多实例负载均衡

Nginx 配置

nginx
upstream vllm_backend {
    least_conn;  # 最少连接数策略
    server localhost:8000;
    server localhost:8001;
    server localhost:8002;
}

server {
    listen 80;
    location /v1/ {
        proxy_pass http://vllm_backend/v1/;
        proxy_set_header Host $host;
        proxy_read_timeout 300s;
    }
}

5.2 Kubernetes 自动扩缩容

yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-deployment
  minReplicas: 1
  maxReplicas: 5
  metrics:
    - type: Pods
      pods:
        metric:
          name: vllm_num_requests_waiting
        target:
          type: AverageValue
          averageValue: "5"

5.3 KServe 模型服务

yaml
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: llama2-7b
spec:
  predictor:
    containers:
      - name: kserve-container
        image: vllm/vllm-openai:latest
        args:
          - --model
          - meta-llama/Llama-2-7b-hf
        resources:
          limits:
            nvidia.com/gpu: 1

6. API 网关与路由

6.1 LiteLLM(统一多模型接入)

python
from litellm import completion

# 统一调用不同后端
response = completion(
    model="vllm/llama2-7b",  # 或 "openai/gpt-4", "ollama/llama3"
    messages=[{"role": "user", "content": "你好"}],
    api_base="http://localhost:8000",
)

6.2 请求路由策略

策略说明适用场景
轮询依次分发到各实例实例性能一致
最少连接分发到当前连接最少的实例请求处理时间差异大
智能路由根据模型能力/成本选择后端多模型混合部署
会话保持同一用户路由到同一实例有状态对话

参考资源


相关页面

AI Knowledge Base — 持续积累