1. 场景:什么时候需要自己部署大模型
去年底我接到一个金融客户的项目,需求很明确:内部知识库问答系统,所有数据处理必须在私有环境完成,不能调用任何外部 API。
这不是个例。随着大模型在企业场景的深入应用,越来越多团队面临同样的抉择:
- 数据合规:金融、医疗、政务行业要求数据不出域
- 成本控制:日均调用量超过百万 Token 时,API 费用远超自建成本
- 定制需求:需要对模型做微调或接入自定义推理逻辑
- 稳定性:不能依赖外部服务的可用性
API 调用 vs 私有部署的适用场景
| 维度 | 百炼 API 调用 | ECS 私有部署 |
|---|---|---|
| 数据安全 | 数据经公网传输 | 数据完全内网闭环 |
| 启动成本 | 零,按量付费 | GPU 实例 + 环境搭建 |
| 适合阶段 | 原型验证、低频调用 | 生产级、高频调用 |
| 定制能力 | 仅 Prompt 工程 | 微调、推理逻辑全可控 |
| 响应延迟 | 受网络影响 | 内网毫秒级 |
部署方式决策树
不是所有场景都需要 ECS 部署,选择合适的部署方式才能平衡成本和效率:

本文聚焦决策树中的 ECS GPU 实例部署路径,这是私有化部署最常见也最灵活的方式。
2. GPU 实例选型
选型是整个部署流程中最关键的决策,选错实例意味着要么显存不够跑不起来,要么花冤枉钱买过剩算力。
阿里云 GPU 实例族对比
阿里云 2026 年在售的 GPU 实例族主要有三款,定位差异明显:
| 实例族 | GPU 型号 | 典型规格 | 适用场景 | 按量价格(参考) |
|---|---|---|---|---|
| ecs.gn7i | NVIDIA A10 | 1/2/4 卡 | 推理为主,性价比首选 | ¥8-32/小时 |
| ecs.gn8i | NVIDIA L4 | 1/2/4 卡 | 推理+轻量训练,新一代 | ¥10-40/小时 |
| ecs.ebmgn8v | NVIDIA H20 | 8 卡 | 大规模训练+推理 | ¥120/小时 |
我的选择:部署 Qwen3-14B 推理服务,选用
ecs.gn7i-c16g1.4xlarge(1 卡 A10 24GB),性价比最优。
模型参数量 vs GPU 显存需求
不同参数量的 Qwen3 模型对 GPU 显存的需求差异巨大,选型前务必算清楚:
| 模型 | 参数量 | FP16 显存需求 | INT4 显存需求 | 推荐实例 |
|---|---|---|---|---|
| Qwen3-4B | 40 亿 | ~8 GB | ~3 GB | ecs.gn7i(1卡A10) |
| Qwen3-14B | 140 亿 | ~28 GB | ~8 GB | ecs.gn7i(1卡A10,INT4) |
| Qwen3-32B | 320 亿 | ~64 GB | ~18 GB | ecs.gn7i(2卡A10) |
| Qwen3-72B | 720 亿 | ~144 GB | ~38 GB | ecs.gn7i(4卡A10) |
关键公式:FP16 显存 ≈ 参数量 × 2 字节 + KV Cache + 运行开销。INT4 量化后显存约为 FP16 的 1/4。
成本估算
为什么需要先算账:GPU 实例按小时计费,包年包月和按量付费价差可达 60%。
| 计费方式 | ecs.gn7i-c16g1.4xlarge 月费 | 适合场景 |
|---|---|---|
| 按量付费 | ~¥5,760(24h×30d×¥8/h) | 短期测试、临时需求 |
| 包年包月 | ~¥3,200/月 | 长期稳定运行 |
| 抢占式实例 | ~¥1.5/小时 | 容错推理、开发测试 |
省钱建议:先用按量付费验证环境,确认无误后切换包年包月。开发测试阶段可用抢占式实例,价格仅为按量的 20%。
查看 GPU 信息
为什么需要确认 GPU 状态:实例启动后必须验证驱动和 GPU 是否正常识别,避免后续部署白忙一场。
# 查看 GPU 设备信息
nvidia-smi
# 查看 CUDA 版本
nvcc --version
# 查看 GPU 数量和型号
nvidia-smi --query-gpu=name,memory.total --format=csv
预期输出类似:
name, memory.total [MiB]
NVIDIA A10, 24576 MiB
3. 环境配置
环境配置是整个流程中最容易出问题的环节,一个版本不匹配就可能导致后续推理服务启动失败。
操作系统选择
推荐 Ubuntu 22.04 LTS,理由很简单:
- 阿里云 GPU 镜像基于 Ubuntu 22.04 做了深度适配
- CUDA 12.x 官方支持 Ubuntu 22.04
- 社区文档和排错资料最丰富
避坑:不要选 CentOS,NVIDIA 已停止对 CentOS 的官方支持,驱动兼容性问题多。
CUDA 和 cuDNN 安装
为什么不用阿里云 GPU 镜像:GPU 镜像预装了 CUDA 但版本可能不是最新的,手动安装可以精确控制版本。
# 安装 CUDA 12.4(适配 vLLM 0.8.x)
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run
sudo sh cuda_12.4.0_550.54.14_linux.run
# 配置环境变量
echo 'export PATH=/usr/local/cuda-12.4/bin:$PATH' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH=/usr/local/cuda-12.4/lib64:$LD_LIBRARY_PATH' >> ~/.bashrc
source ~/.bashrc
# 验证 CUDA 安装
nvcc --version
Python 虚拟环境配置
为什么用 Conda 而不是 venv:大模型依赖库版本冲突严重,Conda 管理更省心。
# 安装 Miniconda
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
bash Miniconda3-latest-Linux-x86_64.sh -b -p $HOME/miniconda3
source ~/miniconda3/bin/activate
# 创建虚拟环境
conda create -n qwen3 python=3.11 -y
conda activate qwen3
# 验证 Python 版本
python --version
模型权重下载
为什么用 ModelScope 而不是 HuggingFace:国内网络环境下,ModelScope 下载速度是 HuggingFace 的 10 倍以上。
# 安装 modelscope
pip install modelscope
# 下载 Qwen3-14B 模型权重
modelscope download \
--model Qwen/Qwen3-14B \
--local_dir /data/models/Qwen3-14B
# 验证模型文件完整性
ls -lh /data/models/Qwen3-14B/
# 预期看到:config.json, model.safetensors 等文件
避坑:模型文件动辄几十 GB,确保系统盘或数据盘有足够空间。建议挂载 ESSD PL1 云盘作为数据盘,单独存放模型权重。
4. vLLM 推理引擎部署
为什么选 vLLM 而不是其他推理框架:vLLM 的 PagedAttention 技术将显存利用率提升到 95% 以上,吞吐量是原生 Transformers 的 3-5 倍。
vLLM 核心优势
| 特性 | 原生 Transformers | vLLM |
|---|---|---|
| 显存管理 | 静态预分配 | PagedAttention 动态管理 |
| 批处理 | 静态批处理 | 连续批处理(Continuous Batching) |
| 显存利用率 | ~60% | ~95% |
| 吞吐量 | 基准 | 3-5x 提升 |
vLLM 安装
为什么指定版本:vLLM 更新频繁,不同版本对模型的支持和 API 有差异,锁定版本确保可复现。
# 安装 vLLM 0.8.x
pip install vllm==0.8.5
# 验证安装
python -c "import vllm; print(vllm.__version__)"
启动 Qwen3 推理服务
为什么这些参数需要调优:默认参数无法发挥 GPU 全部性能,根据模型大小和业务场景调整才能获得最优推理效果。
# 启动 vLLM 推理服务(Qwen3-14B,INT4 量化)
python -m vllm.entrypoints.openai.api_server \
--model /data/models/Qwen3-14B \
--served-model-name qwen3-14b \
--quantization awq \
--tensor-parallel-size 1 \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code
关键参数说明:
| 参数 | 说明 | 调优建议 |
|---|---|---|
--quantization awq |
INT4 量化,显存降至 1/4 | 14B 模型单卡 A10 必须开启 |
--tensor-parallel-size |
张量并行卡数 | 单卡设 1,多卡按 GPU 数量设置 |
--gpu-memory-utilization |
GPU 显存使用比例 | 建议 0.85-0.95,留余量防 OOM |
--max-model-len |
最大上下文长度 | 越大越占显存,按业务需求设置 |
验证推理服务
# 测试推理服务是否正常
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "qwen3-14b",
"messages": [{"role": "user", "content": "你好,请介绍一下你自己"}],
"max_tokens": 256
}'
5. Nginx 反向代理与 API 封装
为什么需要 Nginx:生产环境不能让客户端直连 vLLM,需要 Nginx 做 SSL 终结、限流和负载均衡。
部署架构

Nginx 配置
为什么配置这些参数:长文本生成可能耗时 30 秒以上,Nginx 默认超时 60 秒会导致请求中断。
# /etc/nginx/conf.d/ai-api.conf
# 限流区域定义
limit_req_zone $binary_remote_addr zone=ai_limit:10m rate=30r/s;
upstream vllm_backend {
# 多实例负载均衡
server 127.0.0.1:8000 weight=1;
server 127.0.0.1:8001 weight=1;
keepalive 32;
}
server {
listen 443 ssl http2;
server_name ai-api.example.com;
# SSL 证书配置
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
# 关键:代理超时设置,长文本生成需要足够时间
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# SSE 流式响应支持
proxy_buffering off;
proxy_cache off;
location /v1/ {
limit_req zone=ai_limit burst=50 nodelay;
proxy_pass http://vllm_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 Connection "";
}
# 健康检查端点
location /health {
proxy_pass http://vllm_backend/health;
access_log off;
}
}
健康检查脚本
为什么需要健康检查:vLLM 进程可能因 OOM 静默退出,Nginx 需要及时摘除异常实例。
# 健康检查脚本 /opt/scripts/health_check.sh
#!/bin/bash
HEALTH_URL="http://127.0.0.1:8000/health"
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" $HEALTH_URL)
if [ "$RESPONSE" != "200" ]; then
echo "$(date): vLLM service unhealthy, restarting..." >> /var/log/vllm-health.log
systemctl restart vllm
fi
# 添加到 crontab,每 30 秒检查一次
* * * * * /opt/scripts/health_check.sh
* * * * * sleep 30 && /opt/scripts/health_check.sh
6. 性能测试与优化
不做压测就上线,等于盲人开车。必须用数据验证推理服务能否承受生产流量。
压测工具和核心指标
| 指标 | 全称 | 含义 | 目标值 |
|---|---|---|---|
| TTFT | Time To First Token | 首 Token 延迟 | < 500ms |
| Throughput | Tokens/s | 每秒生成 Token 数 | > 100 tokens/s |
| Latency P99 | 99 分位延迟 | 99% 请求的响应时间 | < 5s |
压测脚本
为什么用这个脚本:需要模拟真实并发场景,测量不同负载下的服务表现。
# benchmark.py - 简易压测脚本
import asyncio
import time
import httpx
import statistics
API_URL = "http://127.0.0.1:8000/v1/chat/completions"
CONCURRENT = [1, 5, 10, 20, 50]
async def send_request(client, prompt):
start = time.time()
resp = await client.post(API_URL, json={
"model": "qwen3-14b",
"messages": [{
"role": "user", "content": prompt}],
"max_tokens": 256
})
latency = time.time() - start
data = resp.json()
tokens = data["usage"]["completion_tokens"]
return latency, tokens
async def run_benchmark(concurrency, num_requests=50):
prompt = "请详细解释微服务架构的优缺点"
async with httpx.AsyncClient(timeout=120) as client:
tasks = [send_request(client, prompt) for _ in range(num_requests)]
results = await asyncio.gather(*tasks)
latencies = [r[0] for r in results]
total_tokens = sum(r[1] for r in results)
total_time = max(latencies)
print(f"并发={concurrency} | "
f"P50={statistics.median(latencies):.2f}s | "
f"P99={sorted(latencies)[int(0.99*len(latencies))]:.2f}s | "
f"吞吐={total_tokens/total_time:.1f} tokens/s")
async def main():
for c in CONCURRENT:
await run_benchmark(c)
asyncio.run(main())
Qwen3-14B 性能测试数据
以下为 ecs.gn7i-c16g1.4xlarge(1 卡 A10)上 Qwen3-14B AWQ 量化的实测数据:
| 并发数 | TTFT | P50 延迟 | P99 延迟 | 吞吐量 |
|---|---|---|---|---|
| 1 | 320ms | 2.1s | 2.8s | 85 tokens/s |
| 5 | 580ms | 3.5s | 5.2s | 120 tokens/s |
| 10 | 950ms | 5.8s | 8.1s | 135 tokens/s |
| 20 | 1800ms | 9.2s | 14.5s | 110 tokens/s |
| 50 | 3500ms | 18.6s | 30.2s | 65 tokens/s |
结论:单卡 A10 部署 Qwen3-14B AWQ,最佳并发在 10-20 之间,超过 20 并发吞吐量开始下降。
优化技巧
| 优化手段 | 原理 | 效果 |
|---|---|---|
| KV Cache | 缓存已计算的 Key/Value | TTFT 降低 40% |
| Prefix Caching | 缓存公共前缀的 KV | 系统提示词场景 TTFT 降低 60% |
| Speculative Decoding | 小模型猜测+大模型验证 | 吞吐量提升 1.5-2x |
启用 Prefix Caching 的启动命令:
# 启用 Prefix Caching(适合系统提示词固定的场景)
python -m vllm.entrypoints.openai.api_server \
--model /data/models/Qwen3-14B \
--served-model-name qwen3-14b \
--quantization awq \
--enable-prefix-caching \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code
7. 生产环境运维
服务上线只是开始,运维才是持久战。没有监控的线上服务,等于蒙眼狂奔。
监控方案
为什么选 Prometheus + Grafana:vLLM 原生暴露 Prometheus 指标,开箱即用,无需额外开发。
# 安装 Prometheus
wget https://github.com/prometheus/prometheus/releases/download/v2.52.0/prometheus-2.52.0.linux-amd64.tar.gz
tar xzf prometheus-2.52.0.linux-amd64.tar.gz
cd prometheus-2.52.0.linux-amd64
Prometheus 配置文件:
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'vllm'
static_configs:
- targets: ['localhost:8000/metrics']
metrics_path: /metrics
scrape_interval: 10s
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
关键监控指标
| 指标 | 含义 | 告警阈值 |
|---|---|---|
vllm:num_requests_running |
正在处理的请求数 | > 80% max |
vllm:gpu_cache_usage_perc |
GPU KV Cache 使用率 | > 90% |
vllm:avg_generation_throughput |
平均生成吞吐量 | < 50 tokens/s |
vllm:num_requests_waiting |
排队等待的请求数 | > 20 |
日志管理
为什么日志要落盘:vLLM 的 OOM 错误只在日志中体现,不配置日志轮转磁盘会很快打满。
# vLLM systemd 服务配置
# /etc/systemd/system/vllm.service
[Unit]
Description=vLLM Inference Server
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/vllm
ExecStart=/root/miniconda3/envs/qwen3/bin/python -m vllm.entrypoints.openai.api_server \
--model /data/models/Qwen3-14B \
--served-model-name qwen3-14b \
--quantization awq \
--gpu-memory-utilization 0.90 \
--max-model-len 8192 \
--host 0.0.0.0 \
--port 8000 \
--trust-remote-code
Restart=on-failure
RestartSec=10
StandardOutput=append:/var/log/vllm/stdout.log
StandardError=append:/var/log/vllm/stderr.log
[Install]
WantedBy=multi-user.target
# 日志轮转配置 /etc/logrotate.d/vllm
/var/log/vllm/*.log {
daily
rotate 7
compress
missingok
notifempty
copytruncate
}
自动扩缩容策略
为什么需要自动扩缩容:业务流量有明显波峰波谷,固定实例数要么浪费要么扛不住。
| 策略 | 触发条件 | 动作 |
|---|---|---|
| 请求排队扩容 | num_requests_waiting > 20 持续 3 分钟 |
新增 ECS 实例 |
| 低负载缩容 | GPU 利用率 < 30% 持续 15 分钟 | 释放 ECS 实例 |
| 定时扩缩容 | 工作日 9:00-18:00 | 预置实例数 |
实现方式:通过阿里云 OOS(运维编排服务)+ 自定义监控脚本,实现基于指标的自动扩缩容。具体配置因业务而异,此处不展开。
模型热更新
为什么需要热更新:模型迭代频繁,不能每次更新都停服。
# 模型热更新流程(不停服切换)
# 1. 下载新模型到独立目录
modelscope download --model Qwen/Qwen3-14B --local_dir /data/models/Qwen3-14B-v2
# 2. 启动新的 vLLM 实例(不同端口)
python -m vllm.entrypoints.openai.api_server \
--model /data/models/Qwen3-14B-v2 \
--port 8001 \
...
# 3. Nginx 灰度切换(逐步将流量切到新实例)
# 4. 确认新实例稳定后,停止旧实例
8. 成本分析
成本是技术决策的最终考量。不算清楚账,技术方案再优雅也无法落地。
月度成本拆解
以 ecs.gn7i-c16g1.4xlarge(1 卡 A10)包年包月为例:
| 资源项 | 规格 | 月费 |
|---|---|---|
| GPU 实例 | ecs.gn7i-c16g1.4xlarge | ¥3,200 |
| 系统盘 | ESSD PL0 40GB | ¥12 |
| 数据盘 | ESSD PL1 200GB(存模型) | ¥140 |
| 公网带宽 | 按流量 5Mbps | ¥50 |
| 合计 | ¥3,402/月 |
与百炼 API 成本对比
关键问题:调用量达到多少时,自建比 API 更划算?
| 调用量级 | 百炼 API 月费 | ECS 自建月费 | 结论 |
|---|---|---|---|
| 100 万 Token/天 | ¥1,500 | ¥3,402 | API 更划算 |
| 500 万 Token/天 | ¥7,500 | ¥3,402 | 自建更划算 |
| 1000 万 Token/天 | ¥15,000 | ¥3,402 | 自建优势明显 |
成本临界点:日均调用量约 300 万 Token 时,ECS 自建与百炼 API 成本持平。超过此临界点,自建成本优势随调用量线性增长。
省钱技巧
- 抢占式实例:开发测试阶段使用,价格仅为按量的 20%
- 预留实例券:长期使用购买 RI,可再降 30%
- 存储优化:模型权重存 OSS,按需挂载,节省数据盘费用
- 闲时关机:非 7×24 场景,配置定时开关机
9. 避坑指南
每个坑都是真金白银买来的教训,希望你能绕过。
坑 1:GPU 实例库存不足
现象:创建实例时提示"当前可用区库存不足"。
原因:GPU 实例属于稀缺资源,热门可用区经常售罄。
解决方案:
# 查询可用区库存(阿里云 CLI)
aliyun ecs DescribeAvailableResource \
--RegionId cn-beijing \
--DestinationResource InstanceType \
--InstanceType ecs.gn7i-c16g1.4xlarge \
--ZoneId cn-beijing-g
- 多选几个可用区(如 cn-beijing-g、cn-beijing-h)
- 错峰购买,工作日上午库存相对充足
- 包年包月优先级高于按量付费
坑 2:模型下载速度慢
现象:从 HuggingFace 下载模型,速度只有几十 KB/s。
解决方案:
# 方案一:使用 ModelScope 镜像(推荐)
pip install modelscope
modelscope download --model Qwen/Qwen3-14B --local_dir /data/models/Qwen3-14B
# 方案二:使用 HuggingFace 镜像站
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Qwen/Qwen3-14B --local-dir /data/models/Qwen3-14B
# 方案三:先下载到 OSS,再内网传输(最快)
# 本地下载 → 上传 OSS → ECS 内网拉取
坑 3:vLLM 显存溢出
现象:启动后运行一段时间,日志出现 CUDA out of memory。
排查步骤:
# 1. 查看实时 GPU 显存使用
watch -n 1 nvidia-smi
# 2. 检查 vLLM 日志中的 OOM 记录
grep -i "out of memory" /var/log/vllm/stderr.log
# 3. 查看当前 KV Cache 使用率
curl http://localhost:8000/metrics | grep gpu_cache_usage
解决方案:
- 降低
--gpu-memory-utilization(0.90 → 0.85) - 减小
--max-model-len(8192 → 4096) - 启用 AWQ/GPTQ 量化
- 升级到更大显存的实例
坑 4:Nginx 超时导致长文本生成中断
现象:生成长文本时,客户端收到 504 Gateway Timeout。
原因:Nginx 默认 proxy_read_timeout 为 60 秒,长文本生成可能超过。
解决方案:
# 关键:三个超时参数必须同时调大
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
# 流式响应必须关闭缓冲
proxy_buffering off;
proxy_cache off;
# 如果使用 SSE 流式接口,还需添加
proxy_set_header Connection '';
proxy_http_version 1.1;
chunked_transfer_encoding on;
坑 5:安全组配置遗漏
现象:服务在本机可以访问,但外部无法连接。
检查清单:
- 安全组入方向是否放行 443(HTTPS)端口
- 安全组入方向是否放行 22(SSH)端口
- 是否误设了 source IP 限制
- ECS 实例是否分配了公网 IP 或绑定 EIP
# 快速验证端口是否通
# 在外部机器执行
curl -v https://ai-api.example.com/health
# 在 ECS 上检查端口监听
ss -tlnp | grep -E '443|8000'
10. 总结
自主部署 vs API 调用选择建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 个人学习、快速验证 | 百炼 API | 零成本启动 |
| 团队内部工具 | 函数计算 FC | 免运维 |
| 企业私有化、数据合规 | ECS GPU 实例 | 数据不出域 |
| 大规模生产服务 | ACK 容器集群 | 高可用可扩展 |
全流程回顾
从选型到上线,核心步骤只有五步:
- 选型:根据模型参数量确定 GPU 实例规格
- 环境:CUDA + Conda + 模型权重,版本要对齐
- 推理:vLLM 启动服务,调优关键参数
- 代理:Nginx 反向代理,SSL + 限流 + 超时
- 运维:监控 + 日志 + 扩缩容,保障线上稳定
最后提醒:部署只是手段,业务价值才是目的。不要为了部署而部署,先想清楚是否真的需要私有化,再动手不迟。
📜 真实性声明
本文所有技术方案和命令均基于作者在阿里云 ECS 上的实际部署验证。性能数据来自本地测试环境,仅供参考,实际表现因配置和负载而异。文中涉及的阿里云产品价格基于 2026 年 6 月公开信息,请以阿里云官网实时价格为准。