模型下载:
一般通过modelscope提供的方式进行下载,速度更快,huggingface下模型即便开启了魔法也还是很慢,对于9B以上的模型都是至少15G的。
比如需要下载qwen3-embedding-8b的模型,可以通过提供的一段代码自动进行下载到/root/.cache中
#Model Download
from modelscope import snapshot_download
model_dir = snapshot_download('Qwen/Qwen3-Embedding-8B')
VLLM库介绍
vLLM 是一个为大型语言模型(LLM)推理和部署服务而设计的、主打高性能和高内存效率的开源库。它最初由加州大学伯克利分校的研究人员开发,现在已经成为一个由社区驱动的活跃项目,并由 PyTorch 基金会托管。
简单来说,vLLM 的核心目标是让 LLM 的运行更快、更省钱、更容易。无论是进行离线批量处理还是部署在线服务,vLLM 都能显著提升模型的推理速度和吞吐量(即单位时间内处理请求的数量)。
vLLM 为何如此高效?核心技术:PagedAttention
vLLM 实现卓越性能的关键在于其创新的 PagedAttention 算法。
灵感来源:PagedAttention 的思想借鉴了操作系统中经典的“虚拟内存”和“分页”技术。
解决痛点:传统的大模型推理系统在处理注意力机制中的键值缓存(KV Cache)时效率低下。 KV Cache 需要占用大量 GPU 显存,并且由于每个请求生成的文本长度不同,会导致严重的内存碎片和浪费。研究发现,现有系统对显存的利用率可能低至 20%-40%。
工作原理:
内存分页管理:PagedAttention 将庞大的 KV Cache 分割成许多个固定大小的“块”(Block)。这些块可以像操作系统的内存页一样,存储在非连续的显存空间中。
近乎零浪费:通过这种方式,vLLM 几乎消除了内存碎片,让显存的利用率接近 100%,从而可以在相同的硬件上处理更大批次的请求。
高效内存共享:当多个请求(例如,使用相同开头提示词的并行生成)需要共享部分计算结果时,PagedAttention 可以通过共享内存块来实现,极大地减少了内存开销,使得并行采样、束搜索(Beam Search)等复杂生成策略的运行成本更低。
得益于 PagedAttention,vLLM 的吞吐量可以达到 HuggingFace Transformers 的 24 倍之多,并且无需对模型架构做任何修改。
vLLM 的主要特性与优势
极致的吞吐量:通过 PagedAttention 和持续批处理(Continuous Batching)技术,vLLM 可以高效地将多个请求打包处理,最大化 GPU 的利用率,实现业界领先的推理吞吐量。
高效的内存管理:显著降低显存占用,这意味着用户可以用更少的硬件资源运行更大的模型,或者在同等硬件上获得更高的性能,从而降低成本。
易于使用和部署:
离线推理:提供了简单的 Python API(vllm.LLM 类),只需几行代码即可加载模型并进行推理。
在线服务:通过一条命令(vllm serve)即可启动一个与 OpenAI API 兼容的服务器。这意味着许多现有的、基于 OpenAI API 开发的应用可以无缝切换到由 vLLM 驱动的本地模型,极大地简化了部署流程。
广泛的兼容性:
模型支持:无缝支持 Hugging Face 生态中绝大多数热门的开源模型,包括 Llama、Mixtral、Gemma 等多种架构。同时,它也开始支持多模态模型。
硬件支持:主要针对 NVIDIA GPU 进行了深度优化,同时也支持 AMD GPU、AWS Neuron 等多种硬件。
丰富的高级功能:
量化支持:支持 GPTQ、AWQ、FP8 等多种量化技术,进一步压缩模型体积,提升推理速度。
分布式推理:支持张量并行和流水线并行,能够将超大模型部署在多张 GPU 上。
流式输出:支持像 ChatGPT 一样逐字生成并返回结果。
多 LoRA 适配:支持同时加载和运行多个 LoRA 适配器,适用于需要为不同客户或任务提供定制化服务的场景。
如何开始使用 vLLM?
使用 vLLM 非常直接:
安装:通常通过 pip install vllm 即可完成安装。需要注意的是,要确保本地的 NVIDIA 驱动、CUDA 版本与 PyTorch 版本相互兼容。
用于离线批量推理:
from vllm import LLM, SamplingParams# 从 Hugging Face Hub 加载模型 llm = LLM(model="meta-llama/Meta-Llama-3-8B-Instruct")# 定义采样参数 sampling_params = SamplingParams(temperature=0.8, top_p=0.95)# 生成文本 outputs = llm.generate("你好,中国的首都是", sampling_params)# 打印结果 print(outputs[0].outputs[0].text)
部署为在线服务:
在终端中运行以下命令:python -m vllm.entrypoints.openai.api_server \--model "meta-llama/Meta-Llama-3-8B-Instruct"
该命令会启动一个监听在 localhost:8000 的服务,你可以像调用 OpenAI API 一样,通过 curl 或任何 HTTP 客户端来请求这个服务。
使用 curl 命令行工具和使用 Python 的 openai 库。
假设你已经通过以下命令在本地启动了服务,模型为 meta-llama/Meta-Llama-3-8B-Instruct:
codeBash
python -m vllm.entrypoints.openai.api_server --model "meta-llama/Meta-Llama-3-8B-Instruct"
服务会默认运行在 http://localhost:8000。
方式一:使用 curl 命令行工具
curl 是一个强大的命令行工具,用于发送网络请求。这对于快速测试和脚本编写非常方便。
1. 调用“Completions”接口 (适用于旧版模型)
这个接口主要用于文本补全,你提供一个提示(prompt),模型会接着往下写。
curl http://localhost:8000/v1/completions \-H "Content-Type: application/json" \-d '{"model": "meta-llama/Meta-Llama-3-8B-Instruct","prompt": "中国的首都是","max_tokens": 50,"temperature": 0.7}'
参数解释:
http://localhost:8000/v1/completions: 这是 vLLM 服务的 Completions API 端点。
-H "Content-Type: application/json": 指定我们发送的数据是 JSON 格式。
-d '{...}': 指定要发送的数据体 (data body)。
"model": 指定要使用的模型。vLLM 服务器会加载你在启动时指定的模型。
"prompt": 你的输入提示。
"max_tokens": 控制生成文本的最大长度。
"temperature": 控制生成文本的创造性。值越低越确定,越高越随机。
2. 调用“Chat Completions”接口 (推荐,适用于现代对话模型)
这个接口是为对话型模型设计的,输入的是一个消息列表(messages list),可以包含系统、用户和助手的多轮对话历史。Llama 3 Instruct 这类指令微调模型使用这个接口更合适。
curl http://localhost:8000/v1/chat/completions \-H "Content-Type: application/json" \-d '{"model": "meta-llama/Meta-Llama-3-8B-Instruct","messages": [{"role": "system", "content": "你是一个乐于助人的AI助手。"},{"role": "user", "content": "你好,请问中国的首都是哪里?"}],"max_tokens": 50,"temperature": 0.7}'
参数解释:
http://localhost:8000/v1/chat/completions: 这是 vLLM 服务的 Chat Completions API 端点。
"messages": 一个消息对象数组,用来提供对话上下文。
"role": 角色,可以是 system (系统指令)、user (用户提问) 或 assistant (模型之前的回答)。
"content": 消息的具体内容。
方式二:使用 Python 的 openai 库
这是在应用程序中最常用、最方便的方式。你需要先安装 openai 库:pip install openai。
然后,你可以编写一个 Python 脚本来调用 vLLM 服务。关键在于 修改 base_url 指向你的本地 vLLM 服务器,并使用一个虚拟的 API 密钥。
import openai# 创建一个 OpenAI 客户端,但将其配置为指向本地的 vLLM 服务器
# 注意:api_key 是必需的,但由于是本地服务,其值可以是任何非空字符串
client = openai.OpenAI(base_url="http://localhost:8000/v1",api_key="not-needed"
)# 调用 Chat Completions 接口
response = client.chat.completions.create(model="meta-llama/Meta-Llama-3-8B-Instruct",messages=[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "What is the capital of China?"}],temperature=0.7,max_tokens=50
)# 打印模型的回复
print(response.choices[0].message.content)
代码解释:
openai.OpenAI(...): 我们实例化一个客户端。
base_url="http://localhost:8000/v1": 这是最关键的一步。它告诉 openai 库不要去请求官方的 api.openai.com,而是请求我们本地运行的 vLLM 服务地址。
api_key="not-needed": 尽管 openai 库要求提供一个 API 密钥,但 vLLM 服务器默认不会对其进行验证,所以你可以填写任何字符串,比如 "not-needed" 或 "sk-..."。
client.chat.completions.create(...): 这部分代码就和调用官方 OpenAI API 的代码完全一样了,参数也一一对应。
这种方式的巨大优势在于,如果你有一个现有的项目是基于 OpenAI API 开发的,你几乎只需要修改 base_url 这一行代码,就可以无缝地将后端从 OpenAI 的付费服务切换到你自己部署的、由 vLLM 驱动的开源模型上,大大降低了迁移成本。
python脚本部署:
import os
import subprocess
import sysdef start_embed_server():cmd = [sys.executable, "-m", "vllm.entrypoints.openai.api_server","--model", "BAAI/bge-m3","--task", "embed","--host", "0.0.0.0","--port", "8101","--api-key", "" ]print("启动嵌入模型服务器...")process = subprocess.Popen(cmd)return processif __name__ == "__main__":server_process = start_embed_server()print("服务器启动在 http://localhost:8101")try:server_process.wait()except KeyboardInterrupt:print("关闭服务器...")server_process.terminate()
代码功能概述
这是一个Python脚本,用于启动vLLM框架的OpenAI API兼容的嵌入模型服务器,使用BAAI/bge-m3模型提供文本嵌入服务。
逐行解析
1. 导入模块
import os
import subprocess
import sys
subprocess
: 用于启动和管理子进程sys
: 用于访问Python解释器相关的功能和参数
2. 服务器启动函数
def start_embed_server():cmd = [sys.executable, "-m", "vllm.entrypoints.openai.api_server","--model", "BAAI/bge-m3","--task", "embed","--host", "0.0.0.0","--port", "8101","--api-key", "" ]
sys.executable
: 当前Python解释器的路径命令参数:
-m vllm.entrypoints.openai.api_server
: 作为模块运行vLLM的OpenAI API服务器--model BAAI/bge-m3
: 指定使用的嵌入模型--task embed
: 指定任务类型为嵌入--host 0.0.0.0
: 监听所有网络接口--port 8101
: 使用8101端口--api-key ""
: 设置空API密钥(无需认证)
3. 启动子进程
process = subprocess.Popen(cmd)
return process
subprocess.Popen()
: 启动新的子进程运行指定命令返回进程对象以便后续管理
4. 主程序逻辑
if __name__ == "__main__":server_process = start_embed_server()print("服务器启动在 http://localhost:8101")
启动服务器并获取进程对象
输出服务器访问地址
5. 进程管理和优雅关闭
try:server_process.wait()
except KeyboardInterrupt:print("关闭服务器...")server_process.terminate()
server_process.wait()
: 等待子进程结束捕获
KeyboardInterrupt
(Ctrl+C)信号server_process.terminate()
: 优雅终止服务器进程
技术要点
vLLM框架: 高性能的LLM推理和服务框架
BAAI/bge-m3模型: 北京智源研究院的多语言文本嵌入模型
OpenAI API兼容: 可以使用OpenAI风格的API调用
子进程管理: 通过subprocess模块管理外部进程
使用方式:
脚本已通过 vLLM 以 OpenAI 兼容协议在 http://localhost:8101/v1 暴露了 Embeddings 服务(模型 BAAI/bge-m3)。可直接按 OpenAI API 的用法访问。
- 基础地址: http://localhost:8101/v1
- 认证: 你启动时 --api-key "",表示不校验;如后续设置了密钥,需加 Authorization: Bearer <YOUR_KEY>
- 主要接口: POST /v1/embeddings
- 必要参数: model: "BAAI/bge-m3", input: "<文本>" 或 ["文本1","文本2"]
curl 示例
curl -X POST "http://localhost:8101/v1/embeddings" \-H "Content-Type: application/json" \-H "Authorization: Bearer any" \-d '{"model": "BAAI/bge-m3","input": ["你好,世界", "hello world"]}'
Python(OpenAI SDK)
from openai import OpenAIclient = OpenAI(base_url="http://localhost:8101/v1", api_key="any") # 无校验时随便填resp = client.embeddings.create(model="BAAI/bge-m3",input=["这是一个测试", "another sample"])print(len(resp.data), len(resp.data[0].embedding))