概述
一个开源的支持高并发的高性能大模型推理引擎。在这篇博客有简单提到过。
modelscope
通过vLLM(或其他平台、框架)部署模型前,需要先下载模型。国内一般使用魔搭社区,模型库里搜索想要下载的模型。输入qwen3
会看到很多个候选项,主要是:
- 参数量不一致;
- 量化版本不一致;
- 提交者不一致。
总之,找到模型下载路径(/Qwen/Qwen3-30B-A3B
)是需要花点时间的。
下载模型有多种方式:
- 通过浏览器下载:打开魔搭页面,默认下载到
C:\Users\johnny\Downloads
目录下。模型文件通常非常大,如Qwen3-30B-A3B-FP8
,分割为7个文件共30+G。Chrome下载效果如下,不便之处在于文件名可辨识度非常低,最后极有可能不知道下载下来的是哪个模型的子文件。而且这么做,也不太专业。
- 通过命令行下载:在有Python和pip的环境下,
pip install modelscope
安装modelscope。使用modelscope命令行下载,如下载reranker模型:modelscope download --model BAAI/bge-reranker-v2-m3 --local_dir /home/models/BAAI/bge-reranker-v2-m3
。 - 通过客户端下载:
vim ms_download.py
,填入如下内容
from modelscope import snapshot_download
import os
os.environ['HTTP_PROXY'] = 'http://192.168.4.123:7890'
os.environ['HTTPS_PROXY'] = 'http://192.168.4.123:7890'
model_dir = snapshot_download('JunHowie/Qwen3-30B-A3B-GPTQ-Int8')
embedding
使用BAAI提供的模型,docker启动命令(一行):
docker run --name=embedding --volume /home/models:/home/models --network=host --workdir=/ --restart=unless-stopped --runtime=nvidia --detach=true docker.1ms.run/dustynv/vllm:0.7.4-r36.4.0-cu128-24.04 python3 -m vllm.entrypoints.openai.api_server --served-model-name BAAI/bge-m3 --task embedding --enable-prefix-caching --model /home/models/BAAI/bge-m3 --host 0.0.0.0 --port 8001 --trust-remote-code
docker logs -f <container_id>
查看日志:
实际上,上述截图还省略掉不少有价值的日志:
- embedding模型只花费2.38s就成功加载权重值,只使用1G内存(显存),这也是被称为小模型的原因,下面的reranker和语音模型也是如此;
- 暴露的端点,即Endpoint,或routes,有很多,不一一列举;
- 端口是8001;本地访问使用
http://0.0.0.0:8001/
或http://localhost:8001
,同一个局域网访问需要使用固定IP形式:http://192.168.4.134:8001/openapi.json
; 192.168.4.123:63143
是什么?
curl请求截图:
postman请求接口如下:
一行命令的可视化效果可能不太好,docker启动命令(多行):
docker run -it \
--name=embedding \
--volume /home/models:/home/models \
--network=host \
--workdir=/ \
--restart=unless-stopped \
--runtime=nvidia \
--detach=true \
dustynv/vllm:0.7.4-r36.4.0-cu128-24.04 \
python3 -m vllm.entrypoints.openai.api_server \
--served-model-name BAAI/bge-m3 \
--task embedding \
--enable-prefix-caching \
--model /home/models/BAAI/bge-m3 \
--host 0.0.0.0 \
--port 8001 \
--trust-remote-code
测试
使用postman简单测试,POST请求,requestBody如下:
{
"model":"BAAI/bge-m3",
"input":"智能家居系统如何帮助提高家庭能源效率?"
}
执行效果如下:
使用更加专业的py脚本来执行测试:
import requests
import concurrent.futures
BASE_URL = "http://192.168.4.134:30011"
MODEL = "BAAI/bge-m3"
def create_request_body():
return {
"model": MODEL,
"input": "智能家居系统如何帮助提高家庭能源效率?"
}
def make_request(request_body):
headers = {
"Content-Type": "application/json"
}
response = requests.post(f"{BASE_URL}/v1/embeddings", json=request_body, headers=headers, verify=False)
return response.json()
def parallel_requests(num_requests):
request_body = create_request_body()
with concurrent.futures.ThreadPoolExecutor(max_workers=num_requests) as executor:
futures = [executor.submit(make_request, request_body) for _ in range(num_requests)]
results = [future.result() for future in concurrent.futures.as_completed(futures)]
return results
if __name__ == "__main__":
num_requests = 50 # Example: Set the number of parallel requests
responses = parallel_requests(num_requests)
for i, response in enumerate(responses):
print(f"Response {i+1}: {response}")
k8s
上面是使用docker方式启动模型,--restart=unless-stopped
参数可以实现自动重启,但是重启(包括探针)机制不如k8s。
将上面的启动脚本扔给GPT,再经过调整,不难得到一个符合k8s或k3s的yaml文件:
# embedding-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vllm-embedding
spec:
replicas: 1
selector:
matchLabels:
app: vllm-embedding
template:
metadata:
labels:
app: vllm-embedding
spec:
nodeSelector:
kubernetes.io/hostname: k3s-master-2
runtimeClassName: nvidia # 需提前配置GPU运行时
containers:
- name: vllm-embedding
image: dustynv/vllm:0.7.4-r36.4.0-cu128-24.04
command: ["python3"]
args:
- "-m"
- "vllm.entrypoints.openai.api_server"
- "--served-model-name"
- "BAAI/bge-m3"
- "--task"
- "embedding" # 关键参数:指定任务类型
- "--enable-prefix-caching"
- "--model"
- "/home/models/BAAI/bge-m3"
- "--host"
- "0.0.0.0"
- "--port"
- "8011"
- "--trust-remote-code"
volumeMounts:
- name: model-storage
mountPath: /home/models
startupProbe:
httpGet:
path: /health
port: 8011
initialDelaySeconds: 120
periodSeconds: 10
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 8011
initialDelaySeconds: 90
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8011
initialDelaySeconds: 90
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 1
volumes:
- name: model-storage
hostPath:
path: /home/models # 主机模型存储路径
---
# embedding-service.yaml
apiVersion: v1
kind: Service
metadata:
name: vllm-embedding-service
spec:
selector:
app: vllm-embedding
ports:
- protocol: TCP
port: 8011 # 集群内部访问端口
targetPort: 8011 # 容器端口
nodePort: 30011
type: NodePort # 外部访问方式
reranker
与embedding经常一起出现的就是重排序,即reranker小模型。魔搭社区地址,一般用BAAI/bge-reranker-v2-m3
直接给出docker启动模型命令:
docker run -it --name=rerank --volume /home/models:/home/models --network=host --workdir=/ --restart=unless-stopped --runtime=nvidia --detach=true dustynv/vllm:0.7.4-r36.4.0-cu128-24.04 python3 -m vllm.entrypoints.openai.api_server --served-model-name BAAI/bge-reranker-v2-m3 --enable-prefix-caching --model /home/models/BAAI/bge-reranker-v2-m3 --host 0.0.0.0 --port 8002 --trust-remote-code
转化为k3s或k8s的yaml文件也很简单,将上面的embedding模型的yaml文件稍加改动即可。
语音
此处的语言模型指的是ASR模型,参考语音转文本ASR、文本转语音TTS。
魔搭社区地址为iic/SenseVoiceSmall
。启动SenseVoiceSmall模型的镜像不是vLLM,需要自己构建Docker镜像。如果转换为k3s yaml文件,则还需要将Docker镜像转化成crictl镜像。具体参考docker、ctr、crictl命令简介与使用。
使用开源代码仓库,Fork到公司内部代码仓库地址,调整一些配置,维护自己的Dockerfile,即可自主构建Docker镜像。
比如准备好如下Docker镜像:
对于语言模型,其yaml文件也非常简单:
apiVersion: apps/v1
kind: Deployment
metadata:
name: sense-voice
labels:
app: sense-voice
spec:
replicas: 1
selector:
matchLabels:
app: sense-voice
template:
metadata:
labels:
app: sense-voice
spec:
containers:
- name: sense-voice
image: harbor.tesla.com/agent/sense-voice-api:arm64-9a358d5f-2025-05-07-18-46-55
imagePullPolicy: IfNotPresent
env:
- name: model_path
value: "/mnt/models/BAAI/SenseVoiceSmall"
volumeMounts:
- name: model-storage
mountPath: /mnt/models
startupProbe:
httpGet:
path: /health
port: 8003
initialDelaySeconds: 120
periodSeconds: 10
failureThreshold: 3
livenessProbe:
httpGet:
path: /health
port: 8003
initialDelaySeconds: 90
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 8003
initialDelaySeconds: 90
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 1
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "1"
memory: "2Gi"
volumes:
- name: model-storage
hostPath:
path: /mnt/models
---
apiVersion: v1
kind: Service
metadata:
name: sense-voice-service
spec:
selector:
app: sense-voice
ports:
- protocol: TCP
port: 8003 # 服务端口
targetPort: 8003 # 容器端口
nodePort: 30003
type: NodePort # 暴露为NodePort便于外部访问
如果使用k3s部署yaml文件,由于k3s使用的是crictl镜像,k3s会在启动模型时将Docker镜像转换成crictl镜像:
如上图所示,两个镜像其ID是一样的,但crictl镜像更轻量级一些。
vLLM模型部署,下篇