当前位置: 首页 > news >正文

使用VLLM部署大模型embedding/chat 的API

模型下载:


一般通过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 算法。

  1. 灵感来源:PagedAttention 的思想借鉴了操作系统中经典的“虚拟内存”和“分页”技术。

  2. 解决痛点:传统的大模型推理系统在处理注意力机制中的键值缓存(KV Cache)时效率低下。 KV Cache 需要占用大量 GPU 显存,并且由于每个请求生成的文本长度不同,会导致严重的内存碎片和浪费。研究发现,现有系统对显存的利用率可能低至 20%-40%。

  3. 工作原理

    • 内存分页管理: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 非常直接:

  1. 安装:通常通过 pip install vllm 即可完成安装。需要注意的是,要确保本地的 NVIDIA 驱动、CUDA 版本与 PyTorch 版本相互兼容。

  2. 用于离线批量推理

    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)
  3. 部署为在线服务
    在终端中运行以下命令:

    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)

代码解释:

  1. openai.OpenAI(...): 我们实例化一个客户端。

  2. base_url="http://localhost:8000/v1": 这是最关键的一步。它告诉 openai 库不要去请求官方的 api.openai.com,而是请求我们本地运行的 vLLM 服务地址。

  3. api_key="not-needed": 尽管 openai 库要求提供一个 API 密钥,但 vLLM 服务器默认不会对其进行验证,所以你可以填写任何字符串,比如 "not-needed" 或 "sk-..."。

  4. 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(): 优雅终止服务器进程

技术要点

  1. vLLM框架: 高性能的LLM推理和服务框架

  2. BAAI/bge-m3模型: 北京智源研究院的多语言文本嵌入模型

  3. OpenAI API兼容: 可以使用OpenAI风格的API调用

  4. 子进程管理: 通过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))

http://www.dtcms.com/a/347079.html

相关文章:

  • 秋招面试准备
  • Git的下载安装和使用以及和IDEA的关联
  • PLECS 中使用 C-Script 来模拟 NTC 热敏电阻(如 NTC3950B)
  • Spring Boot 校验分组(Validation Groups)高级用法全指南
  • 从词源和输出生成等角度详细解析PHP中常用文件操作类函数
  • Mac简单测试硬盘读写速度
  • 计算机网络 TLS握手中三个随机数详解
  • 鸿蒙应用网络开发实战:HTTP、WebSocket、文件下载与网络检测全攻略
  • Ubuntu 操作系统深度解析:从入门到精通(2025 最新版)
  • AP5414 LED驱动芯片:高效灵活,专业级照明解决方案
  • 20250823解决荣品RD-RK3588-MID核心板的底板的adb不通
  • Unity其他--【MMD】如何在Unity中制作MMD
  • Go数据结构与算法-常见的排序算法
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘arviz’问题
  • Boost.Asio 库中的 async_read_some用法
  • JAVA核心基础篇-操作符
  • 嵌入式LINUX——————网络TCP
  • 如何在Ubuntu中删除或修改已有的IP地址设置?
  • 在Excel和WPS表格中快速插入多行或多列
  • 生成一个竖直放置的div,宽度是350px,上面是标题固定高度50px,下面是自适应高度的div,且有滚动条
  • LeetCode算法日记 - Day 19:判定字符是否唯一、丢失的数字
  • 可转换债券高频交易Level-2五档Tick级分钟历史数据分析
  • 什么?OpenCV调用cv2.putText()乱码?寻找支持中文的方法之旅
  • Vue3+ElementPlus倒计时示例
  • 入校申请|基于SprinBoot+vue的入校申报审批系统(源码+数据库+文档)
  • [激光原理与应用-332]:结构设计 - Solidworks - 特征(Feature)是构成三维模型的基本单元,是设计意图的载体,也是参数化设计的核心。
  • LeetCode 面试经典 150_数组/字符串_找出字符串中第一个匹配项的下标(23_28_C++_简单)(KMP 算法)
  • 「ECG信号处理——(24)基于ECG和EEG信号的多模态融合疲劳分析」2025年8月23日
  • 构建真正自动化知识工作的AI代理
  • 日志搜索系统前端页面(暂无后端功能)