阿里云服务器配置 LLM 推理服务教程

📅 2026/7/23 22:52:53 👁️ 阅读次数 📝 编程学习
阿里云服务器配置 LLM 推理服务教程

一、环境信息(本机实测)

项目
操作系统 Ubuntu 22.04.5 LTS
GPU NVIDIA Tesla V100-SXM2-16GB
驱动版本 570.195.03
CUDA 12.4 (nvcc V12.4.131)
PyTorch 2.4.0+cu118
vLLM dev (claude build)
Python 3.10.12
pip 镜像 https://mirrors.aliyun.com/pypi/simple/
模型 Qwen/Qwen2.5-1.5B-Instruct (2.9 GB)
内存 30 GB

本教程所有命令都是在 root 用户下执行。如果使用普通用户,部分命令前需要加 sudo

二、CUDA & 驱动配置

2.1 检查当前驱动和 CUDA

# 查看 GPU 信息和驱动版本
nvidia-smi# 查看 CUDA 编译器版本
nvcc --version# 或查看 CUDA 版本文件
cat /usr/local/cuda/version.txt 2>/dev/null

2.2 安装 NVIDIA 驱动(如果没有)

# 查看推荐驱动版本
ubuntu-drivers devices# 自动安装推荐驱动
apt install -y nvidia-driver-570# 重启后验证
nvidia-smi

2.3 安装 CUDA(如果没有)

# 从 NVIDIA 官网下载(选对版本)
wget https://developer.download.nvidia.com/compute/cuda/12.4.0/local_installers/cuda_12.4.0_550.54.14_linux.run
sh cuda_12.4.0_550.54.14_linux.run# 添加环境变量(写入 ~/.bashrc)
export PATH=/usr/local/cuda/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
重要提示:PyTorch 的 CUDA 版本可以低于系统 CUDA 版本(向后兼容)。 例如系统装 CUDA 12.4,PyTorch 可以用 cu118(兼容 CUDA 11.8+)。 不要盲目追新,以 PyTorch 官方的兼容列表为准。

三、PyTorch 安装

3.1 配置 pip 镜像(国内服务器必做,否则慢到崩溃)

# 阿里云源(推荐,实测稳定)
pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/# 也可用其他源
# https://pypi.tuna.tsinghua.edu.cn/simple  (清华)
# https://mirrors.ustc.edu.cn/pypi/simple/   (中科大)

3.2 安装 PyTorch

去 PyTorch 历史版本 找到匹配 CUDA 的版本。

V100(计算能力 7.0)不支持 cu124,推荐 cu118:

# CUDA 11.8 + PyTorch 2.4.0(阿里云镜像)
pip install torch==2.4.0 torchvision==0.19.0 torchaudio==2.4.0 \--index-url https://download.pytorch.org/whl/cu118# 验证
python3 -c "import torch; print(f'PyTorch {torch.__version__}, CUDA: {torch.cuda.is_available()}')"
# 输出: PyTorch 2.4.0+cu118, CUDA: True

四、vLLM 安装与配置

4.1 pip 安装 vLLM

# 直接安装(会自动装配套的 PyTorch,但国内建议先装好 PyTorch)
pip install vllm# 如果网不好,从阿里云源安装
pip install vllm -i https://mirrors.aliyun.com/pypi/simple/

4.2 验证安装

python3 -c "import vllm; print(f'vLLM {vllm.__version__}')"# 查看所有支持的参数
vllm serve --help
已知问题 - pyairports 假包:
阿里云 PyPI 上的 pyairports 0.0.1 是 sample 空包,不能 import。
vLLM 依赖 outlines,outlines 依赖 pyairports。
解决方法:修改 outlines 源码,把报错的那一行注释掉:
# 编辑 /usr/local/lib/python3.10/dist-packages/outlines/types/airports.py
# 将第4行:
#   from pyairports.airports import AIRPORT_LIST
# 改为:
#   AIRPORT_LIST = []
或者直接从 PyPI 官方源安装正确的版本:
pip install pyairports --index-url https://pypi.org/simple/

五、模型下载与加载

5.1 从 HuggingFace 下载模型

# 方法1:用 huggingface-cli(推荐,支持断点续传)
pip install huggingface-hub
huggingface-cli download Qwen/Qwen2.5-1.5B-Instruct \--local-dir /root/models/Qwen/Qwen2.5-1.5B-Instruct# 方法2:用镜像站加速(国内必用)
export HF_ENDPOINT=https://hf-mirror.com
huggingface-cli download Qwen/Qwen2.5-1.5B-Instruct \--local-dir /root/models/Qwen/Qwen2.5-1.5B-Instruct# 方法3:用 Python 代码下载
python3 -c "
from huggingface_hub import snapshot_download
snapshot_download('Qwen/Qwen2.5-1.5B-Instruct',local_dir='/root/models/Qwen/Qwen2.5-1.5B-Instruct')
"

5.2 模型文件结构

/root/models/Qwen/Qwen2.5-1.5B-Instruct/
├── config.json          # 模型配置
├── model.safetensors    # 权重文件(2.9 GB)
├── tokenizer.json       # Tokenizer
├── tokenizer_config.json
├── vocab.json
├── merges.txt
└── generation_config.json
建议:模型文件放在 /root/models/ 下统一管理,方便 vLLM 用绝对路径加载。
HF 缓存默认在 ~/.cache/huggingface/hub/,但 vLLM 直接传路径更方便。

六、启动推理服务

6.1 基本启动命令

vllm serve /root/models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 --port 8000 --max-model-len 4096 \--dtype float16 --trust-remote-code --enforce-eager

参数说明:

参数 说明
--host 0.0.0.0 允许外部访问(不设则只能本机访问)
--port 8000 服务端口
--max-model-len 4096 最大上下文长度(越长越耗显存)
--dtype float16 半精度推理,省显存(V100 原生支持)
--trust-remote-code 允许加载自定义模型代码
--enforce-eager 跳过 CUDA Graphs 捕获,加快启动(V100 上推荐)
--gpu-memory-utilization 0.9 GPU 显存利用率(默认 0.9)
--max-num-seqs 256 最大并发请求数

6.2 后台运行(推荐)

nohup vllm serve /root/models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 --port 8000 --max-model-len 4096 \--dtype float16 --trust-remote-code --enforce-eager \> /tmp/vllm.log 2>&1 &

6.3 查看服务和日志

# 查看进程
ps aux | grep vllm | grep -v grep# 查看日志(实时)
tail -f /tmp/vllm.log# 查看端口
ss -tlnp | grep 8000# 停止服务
kill $(ps aux | grep 'vllm serve' | grep -v grep | awk '{print $2}')# 强制停止(杀子进程)
fuser -k 8000/tcp
pkill -9 -f "vllm"

6.4 启动成功的标志

日志最后几行应该看到:

INFO:     Started server process [pid]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on socket ('0.0.0.0', 8000) (Press CTRL+C to quit)

七、外部测试模型

服务启动后,用 curl 直接测试(可以在本机或另一台机器上执行):

7.1 健康检查

curl http://8.159.159.103:8000/health# 返回 200 OK 即正常
# 如返回空,检查日志是否有错误

7.2 聊天测试(一条命令)

curl -s http://8.159.159.103:8000/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "/root/models/Qwen/Qwen2.5-1.5B-Instruct","messages": [{"role": "user", "content": "你好,你是谁?"}],"max_tokens": 100,"temperature": 0.7}' | python3 -m json.tool

7.3 查看可用模型列表

curl -s http://8.159.159.103:8000/v1/models | python3 -m json.tool

7.4 Completion 测试(非聊天模式)

curl -s http://8.159.159.103:8000/v1/completions \-H "Content-Type: application/json" \-d '{"model": "/root/models/Qwen/Qwen2.5-1.5B-Instruct","prompt": "人工智能的未来是","max_tokens": 50}' | python3 -m json.tool

7.5 性能压测

# 简单计时
time curl -s http://8.159.159.103:8000/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "/root/models/Qwen/Qwen2.5-1.5B-Instruct","messages": [{"role":"user","content":"写一首五言绝句"}],"max_tokens": 200}' &>/dev/null

八、外部调用模型(API 方式)

vLLM 提供兼容 OpenAI API 格式的接口,可以直接用 OpenAI 的客户端库调用:

8.1 Python 调用(推荐)

pip install openai
from openai import OpenAIclient = OpenAI(base_url="http://8.159.159.103:8000/v1",api_key="not-needed"  # vLLM 默认不校验 API Key
)# 聊天补全
response = client.chat.completions.create(model="/root/models/Qwen/Qwen2.5-1.5B-Instruct",messages=[{"role": "system", "content": "你是一个有用的助手。"},{"role": "user", "content": "用 Python 写一个冒泡排序"}],max_tokens=500,temperature=0.7
)print(response.choices[0].message.content)# 查看用量
print(f"输入 tokens: {response.usage.prompt_tokens}")
print(f"输出 tokens: {response.usage.completion_tokens}")

8.2 流式输出(SSE)

from openai import OpenAIclient = OpenAI(base_url="http://8.159.159.103:8000/v1",api_key="not-needed"
)stream = client.chat.completions.create(model="/root/models/Qwen/Qwen2.5-1.5B-Instruct",messages=[{"role": "user", "content": "讲个笑话"}],max_tokens=200,stream=True
)for chunk in stream:if chunk.choices[0].delta.content is not None:print(chunk.choices[0].delta.content, end="", flush=True)
print()

8.3 cURL 调用(任何语言通用)

curl -s http://8.159.159.103:8000/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "/root/models/Qwen/Qwen2.5-1.5B-Instruct","messages": [{"role": "system", "content": "你是有用的助手"},{"role": "user", "content": "1+1等于几?"}],"max_tokens": 100,"temperature": 0.7,"stream": false}'

8.4 JavaScript / Node.js 调用

import OpenAI from 'openai';const client = new OpenAI({baseURL: 'http://8.159.159.103:8000/v1',apiKey: 'not-needed',
});const response = await client.chat.completions.create({model: '/root/models/Qwen/Qwen2.5-1.5B-Instruct',messages: [{ role: 'user', content: '你好' }],max_tokens: 100,
});console.log(response.choices[0].message.content);

8.5 安全设置(如需 API Key 校验)

vllm serve /root/models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 --port 8000 \--api-key "your-secret-key-here" \...其他参数

客户端使用时加上 api_key="your-secret-key-here"

安全提醒:如果服务绑定 0.0.0.0 且开放公网,建议:
1. 设置防火墙只允许特定 IP 访问(如使用 Nginx 反向代理)
2. 或设置 --api-key 参数
3. 或只监听内网 IP:--host 192.168.x.x
4. 不要在公网暴露不带认证的 LLM 服务!

九、常见问题

Q1: CUDA out of memory

错误:torch.OutOfMemoryError: CUDA out of memory

原因:显存不足。V100 16GB 跑 1.5B 模型没问题,但之前的进程没释放显存。

解决:

  1. 先杀掉所有残留进程:pkill -9 -f "vllm" && sleep 2
  2. nvidia-smi 确认显存已释放
  3. 减小显存占用参数:--gpu-memory-utilization 0.7--max-model-len 2048
  4. 打开 --enforce-eager 跳过 CUDA Graphs 的额外显存开销
  5. 实在不够可以换更小的模型,如 Qwen2.5-0.5B

Q2: Address already in use(端口被占用)

错误:OSError: [Errno 98] Address already in use

原因:上一个 vLLM 进程没完全退出,或 engine 子进程残留。

解决:

# 方法1:杀掉占用端口的进程
fuser -k 8000/tcp# 方法2:杀掉所有 vLLM 相关进程(包括子进程)
pkill -9 -f "vllm"# 方法3:检查还有什么占着端口
ss -tlnp | grep 8000# 确认释放后再启动
sleep 2 && vllm serve ...

Q3: Engine process failed to start

错误:RuntimeError: Engine process failed to start

原因:引擎子进程启动时崩溃了,但主进程没捕获到详细错误。

解决:

  1. 先检查显存是否足够(nvidia-smi)——OOM 是最常见原因
  2. 查看完整日志:tail -50 /tmp/vllm.log
  3. 直接跑 engine 测试:python3 -c "from vllm.engine.multiprocessing.engine import MQLLMEngine"

Q4: 启动时联网下载模型,但网络不通

错误:Network is unreachable 或连接 huggingface.co 超时

原因:国内服务器访问 HuggingFace 被墙或 DNS 污染。

解决:

# 方案1:改用镜像站
export HF_ENDPOINT=https://hf-mirror.com# 方案2:先手动下载,再用本地路径加载
vllm serve /root/models/Qwen/Qwen2.5-1.5B-Instruct ...# 方案3:用 huggingface-cli 配合镜像站下载
pip install huggingface-hub
HF_ENDPOINT=https://hf-mirror.com huggingface-cli download Qwen/Qwen2.5-1.5B-Instruct

Q5: Internal Server Error (500) 关于 pyairports

错误:ModuleNotFoundError: No module named 'pyairports'

如本文 4.2 节所述,这是阿里云 PyPI 上 pyairports 包为空的问题。

解决:

# 方案1:从官方 PyPI 安装(最快)
pip install pyairports --index-url https://pypi.org/simple/# 方案2:修改 outlines 源码绕过
sed -i "s/from pyairports.airports import AIRPORT_LIST/# fixed\nAIRPORT_LIST = []/" \/usr/local/lib/python3.10/dist-packages/outlines/types/airports.py# 方案3:重启服务(让子进程继承修复)
pkill -9 -f "vllm"
# 重启...

Q6: V100 不支持 FlashAttention

日志:Cannot use FlashAttention-2 backend for Volta and Turing GPUs. Using XFormers backend.

这是正常现象。V100(Volta 架构)不支持 FlashAttention-2,vLLM 会自动切换到 XFormers 后端,不影响功能,只是推理速度比 Ampere 架构稍慢。

Q7: 如何选择模型大小

GPU 显存 推荐最大模型 说明
8 GB 0.5B ~ 1B 如 Qwen2.5-0.5B
16 GB(V100) 1.5B ~ 7B 7B 需 --dtype float16,可加 --enforce-eager
24 GB 7B ~ 13B 可上 Qwen2.5-7B
40 GB+(A100) 13B ~ 70B 70B 需要多卡或量化

Q8: 服务日志太多怎么办

# 启动时加 --disable-log-requests 关闭请求日志
vllm serve ... --disable-log-requests# 只输出错误信息
grep -E "ERROR|Error|Traceback" /tmp/vllm.log

Q9: 监控 GPU 状态

# 实时监控(每秒刷新)
watch -n 1 nvidia-smi# 只查看显存使用
nvidia-smi --query-gpu=memory.used,memory.free --format=csv# 查看进程占用
nvidia-smi pmon -c 1

Q10: 如何开机自启

# 写入 /etc/rc.local 或 systemd service
# 简单方式:在 /root/start_vllm.sh 写入:
cat > /root/start_vllm.sh << 'SCRIPT'
#!/bin/bash
nohup vllm serve /root/models/Qwen/Qwen2.5-1.5B-Instruct \--host 0.0.0.0 --port 8000 --max-model-len 4096 \--dtype float16 --trust-remote-code --enforce-eager \> /tmp/vllm.log 2>&1 &
SCRIPT
chmod +x /root/start_vllm.sh
# 加到 crontab:
# @reboot /root/start_vllm.sh