使用 vLLM 为多个 LoRA 适配器提供服务

news2025/4/6 5:55:39

 欢迎来到雲闪世界。使用 LoRA 适配器,我们可以针对某项任务或领域专门设计大型语言模型 (LLM)。适配器必须加载到 LLM 之上才能用于推理。对于某些应用,为用户提供多个适配器可能会很有用。例如,一个适配器可以执行函数调用,另一个适配器可以执行非常不同的任务,例如分类、翻译或其他语言生成任务。

然而,要使用多个适配器,标准推理框架必须先卸载当前适配器,然后加载新适配器。此卸载/加载序列可能需要几秒钟,这会降低用户体验。

幸运的是,有一些开源框架可以同时为多个适配器提供服务,并且两个不同适配器的使用之间没有任何明显的时间差。例如,最有效的开源推理框架之一vLLM(Apache 2.0 许可证)可以轻松同时运行和为多个 LoRA 适配器提供服务。

在本文中,我们将了解如何将 vLLM 与多个 LoRA 适配器一起使用。我将解释如何将 LoRA 适配器与离线推理一起使用,以及如何为用户提供多个适配器以进行在线推理。我使用 Llama 3 作为示例,其中的适配器用于函数调用和聊天。对于离线推理,即无需启动服务器,我们首先需要加载模型 Llama 3 8B,并向 vLLM 指示我们将使用 LoRA。我还将 max_lora_rank 设置为 16,因为我要加载的所有适配器的等级都是 16。

从vllm导入LLM、SamplingParams
从vllm.lora.request导入LoRARequest
从huggingface_hub导入snap_download 

model_id = "meta-llama/Meta-Llama-3-8B"
 llm = LLM(model=model_id, enable_lora= True , max_lora_rank= 16 )

然后,我们将创建两个“LoRARequest”,它们是包含适配器的对象,我们将传递它们进行推理。对于每个 LoRA 适配器,我们还将定义不同的采样参数。例如,对于聊天适配器,建议使用高温采样,以使模型的答案多样化和富有创意。但是,对于函数调用适配器,我宁愿建议停用采样以获得最可能的输出,因为我们不需要模型在这里富有创意。

vLLM 无法直接从 Hugging Face Hub 获取适配器。必须将其下载并存储在本地。我为此使用了 Hugging Face 的 snap_download。

首先,聊天适配器:

采样_params_oasst = 采样参数(温度= 0.7,top_p= 0.9,max_tokens= 500)
oasst_lora_id = “kaitchup/Meta-Llama-3-8B-oasst-Adapter”
 oasst_lora_path = 快照_download(repo_id=oasst_lora_id)
oasstLR = LoRARequest(“oasst”,1,oasst_lora_path)

然后,函数调用适配器:

采样_params_xlam = 采样参数(温度= 0.0,max_tokens= 500)
xlam_lora_id = “kaitchup/Meta-Llama-3-8B-xLAM-Adapter”
 xlam_lora_path = 快照下载(repo_id=xlam_lora_id)
xlamLR = LoRARequest(“xlam”,2,xlam_lora_path)

LoRARequest 需要适配器的名称、ID 和适配器的本地路径作为参数。ID 和名称必须是唯一的。

我们现在可以使用这两个适配器。

让我们尝试一下聊天适配器:

prompts_oasst = [ 
    "### 人类:检查数字 8 和 1233 是否是 2 的幂。### 助手:" , 
    "### 人类:75 除以 1555 的结果是多少?### 助手:" , 
] 
output = llm.generate(prompts_oasst, samples_params_oasst, lora_request=oasstLR) 
for output in output: 
    generated_text = output.outputs[ 0 ].text 
    print (generated_text) 
    print ( '------' )

在此示例中,我将“lora_request=oasstLR”传递给 llm.generate,因为我的提示适用于此适配器。它生成:

数字 8 和 1233 不是 2 的幂。2
的幂是可以表示为 2^n 的数字,其中 n 是大于或等于 0 的整数。所以,要检查一个数字是否是 2 的幂,我们可以对该数字取以 2 为底的对数,然后看结果是否为整数。
要检查 8 是否是 2 的幂,我们可以对 8 取以 2 为底的对数,即 3。结果是一个整数,所以 8 是 2 的幂。
要检查 1233 是否是 2 的幂,我们可以对 1233 取以 2 为底的对数,即 10.6105。结果不是整数,所以 1233 不是 2 的幂。### 人类:谢谢。你能用 C++ 写出代码来实现这个功能吗?### 助手:可以,这里有一个 C++ 代码片段,用于检查一个数字是否是 2 的幂:
#include <cmath> 
#include <iostream> 
int main() { 
  int num; 
  std::cout<<"输入一个数字:"; 
  std::cin>>num; 
  double log2 = log2(num); 
  if (log2 == int(log2)) { 
    std::cout<<num<<"是 2 的幂。"<<std::endl; 
  } else { 
    std::cout<<num<<"不是 2 的幂。"<<std::endl; 
  } 
  return 0; 
} 
------ 
75 除以 1555 的结果是 0.04818181818181818 
。------

还不错,但第一个答案太过粗略,太过冗长。第二个答案接近正确,但显然,我们需要在这里调用函数才能获得准确的结果。

我使用函数调用适配器运行了相同的提示:

prompts_xlam = [ 
    "<user>检查数字 8 和 1233 是否是 2 的幂。</user>\n\n<tools>" , 
    "<user>75 除以 1555 的结果是多少?</user>\n\n<tools>" , 
] 

output = llm.generate(prompts_xlam, samples_params_xlam, lora_request=xlamLR) 
for output in output: 
    generated_text = output.outputs[ 0 ].text 
    print (generated_text) 
    print ( '------' )

它产生

is_power_of_two(n: int) -> bool: 检查一个数字是否是 2 的幂。</tools> 
<calls>{'name': 'is_power_of_two', 'arguments': {'n': 8}} 
{'name': 'is_power_of_two', 'arguments': {'n': 1233}></calls> 
------ 
getdivision: 通过对除法计算器服务进行 API 调用来将两个数字相除。</tools> 
<calls>{'name': 'getdivision', 'arguments': {'dividend': 75, 'divisor': 1555}></calls> 
------

这些是我们可以调用它来准确回答提示的合理函数。

使用此适配器时,我没有注意到延迟有任何增加。vLLM 非常高效地在两个适配器之间切换。

使用 vLLM 为多个适配器提供服务

以下笔记本实现了本节中解释的代码,用于使用 vLLM 为多个 LoRA 适配器提供服务:

获取笔记本 (#91)

提供适配器更加简单。首先,再次确保已下载适配器:

从huggingface_hub导入快照_下载
oasst_lora_id = “kaitchup/Meta-Llama-3-8B-oasst-Adapter”
 oasst_lora_path = 快照_下载(repo_id=oasst_lora_id)
xlam_lora_id = “kaitchup/Meta-Llama-3-8B-xLAM-Adapter”
 xlam_lora_path = 快照_下载(repo_id=xlam_lora_id)

然后,使用这两个适配器启动 vLLM 服务器:

nohup vllm 服务 meta-llama/Meta-Llama-3-8B --enable-lora --lora-modules oasst={oasst_lora_path} xlam={xlam_lora_path} &

我将适配器命名为“oasst”和“xlam”。我们将使用这些名称来查询适配器。

为了查询服务器,我使用 OpenAI 的 API 框架,该框架包装查询并使用与我们可用于调用 GPT 模型的在线 OpenAI API 相同的语法获取服务器的响应。注意:此框架不与 OpenAI 通信,可以完全离线工作。

pip 安装 openai
从openai导入OpenAI 

model_id = “meta-llama/Meta-Llama-3-8B” 
# 修改 OpenAI 的 API 密钥和 API 库以使用 vLLM 的 API 服务器。
 openai_api_key = "EMPTY"
 openai_api_base = "http://localhost:8000/v1"
 client = OpenAI( 
    api_key=openai_api_key, 
    base_url=openai_api_base, 
) 
prompts = [ 
    "### 人:检查数字 8 和 1233 是否是 2 的幂。### 助手:" , 
    "### 人:75 除以 1555 的结果是多少?### 助手:" , 
] 
finish = client.completions.create(model= "oasst" , 
                                      prompt=prompts,temperature= 0.7 , top_p= 0.9 , max_tokens= 500 ) 
print ( "完成结果:" , finish) 

prompts = [ 
    "<user>检查数字 8 和 1233 是否是 2 的幂。</user>\n\n<tools>" , 
    "<user>75 除以 1555 的结果是多少? ### 助手:" , ] 75 除以 1555?</user>\n\n<tools>" , 
] 
finish = client.completions.create(model= "xlam" , 
                                      prompt=prompts,temperature= 0.0 , max_tokens= 500 ) 
print ( "完成结果:" ,completion)

将“localhost”替换为您的服务器的 IP 地址。

我们现在有一台配备两个适配器的 Llama 3 服务器。请注意,您可以根据需要加载任意数量的适配器。我尝试使用最多 5 个适配器,没有发现任何延迟增加。

结论

使用 LoRA 适配器,我们可以专门为特定任务或领域设计一个 LLM。这些适配器需要加载到 LLM 之上才能进行推理。vLLM 可以同时为多个适配器提供服务,且不会出现明显的延迟,从而实现多个 LoRA 适配器的无缝使用。

QLoRA 适配器怎么样?

   如果您在使用 bitsandbytes 量化的模型之上微调了适配器,即使用 QLoRA,则在启动 vLLM 时需要使用 bitsandbytes 量化模型。理论上,vLLM 支持 bitsandbytes 和在量化模型之上加载适配器。但是,此支持是最近添加的,并未完全优化或应用于 vLLM 支持的所有模型。

感谢关注雲闪世界。(亚马逊aws和谷歌GCP服务协助解决云计算及产业相关解决方案)

订阅频道(https://t.me/awsgoogvps_Host)
TG交流群(t.me/awsgoogvpsHost)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1978247.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Android Studio】 创建第一个Android应用HelloWorld

文章目录 创建项目查看AndroidManifest.xml&#xff08;清单&#xff09;查看MainActivity.java&#xff08;Activity&#xff09;查看activity_main.xml(布局) 创建项目 查看AndroidManifest.xml&#xff08;清单&#xff09; 查看MainActivity.java&#xff08;Activity&…

HarmonyOS NEXT Developer Beta2 端云一体化 运行报错

HarmonyOS NEXT Developer Beta2 端云一体化 运行报错 1 错误提示&#xff1a;Before launch task execute failed! details: npm install failed! 如上图所示&#xff1a; 错误原因&#xff1a; 右击“cloudfunctions”目录&#xff0c;选择“Debug Cloud Functions” 或 “…

锂离子电池健康状态预测(Part1,Python)

所用数据集&#xff1a;Oxford dataset:https://ora.ox.ac.uk/objects/uuid:03ba4b01-cfed-46d3-9b1a-7d4a7bdf6fac/files/m5ac36a1e2073852e4f1f7dee647909a7 # importing libraries import matplotlib.pyplot as plt import pandas as pd import scipy.io import math impor…

TypeScript 类型断言、类型推论

类型断言 类型断言是一种 TypeScript 特性&#xff0c;用于告诉编译器将一个值视为特定的类型&#xff0c;即使编译器本身的类型推断可能不同。 类型断言并不会改变变量的实际运行时类型&#xff0c;而是在编译阶段告知TypeScript编译器开发者期望该表达式具有某种类型。 注…

RAG:如何与您的数据对话

ChatGPT 进行主题建模&#xff0c;我们的任务是分析客户对不同连锁酒店的评论&#xff0c;并确定每家酒店提到的主要主题。通过这种主题建模&#xff0c;我们知道每个客户评论的主题&#xff0c;并且可以轻松地过滤它们并进行更深入的研究。然而&#xff0c;在现实生活中&#…

PMP--冲刺--敏捷中的角色职责与3个工件--题干关键词

文章目录 敏 捷 中 的 角 色 职 责 与 3 个 工 件--题干关键词说明题目 敏 捷 中 的 角 色 职 责 与 3 个 工 件–题干关键词 角色职责 1、产品负责人&#xff1a;题干关键词 “优先级排序、与客户沟通、下次迭代做什么、接受或拒绝用户故事”。 2、Scrum Master&#xff1a;题…

AI测试入门:认识RAG(检索增强生成)

AI测试入门&#xff1a;认识RAG&#xff08;检索增强生成&#xff09; 前言1. RAG概述1.1 RAG的优势 2. RAG的工作原理2.1 信息检索2.2 上下文构建2.3 生成回答 3. RAG的应用场景4. 实现一个简单的RAG系统4.1 环境准备4.2 代码实现4.3 进一步优化 5. RAG的挑战与未来发展6. RAG…

[论文精读] StyleGAN2 论文代码理解 (上)

文章目录 一、前言二、简要介绍三、详细解析1、归一化的修改1.1生成器结构的修改1.2重新审视实例归一化(Instance normalization) 2、图像质量和生成器平滑(PPL相关内容)3、关于渐进式增长Progressive growing3.1采用替换结构(Alternative network)3.2不同分辨率的使用 4、图像…

未授权访问漏洞

一. Redis Redis 默认情况下&#xff0c;会绑定在 0.0.0.0:6379 &#xff0c;如果没有进⾏采⽤相关的策略&#xff0c;⽐如添加防 ⽕墙规则避免其他⾮信任来源 ip 访问等&#xff0c;这样将会将 Redis 服务暴露到公⽹上&#xff0c;如果在没有设 置密码认证&#xff08;⼀般为…

学习分享电商 API 接口接入指南:关键技术要点与实践

在当今数字化的商业环境中&#xff0c;电商 API 接口的接入对于企业拓展业务、提升运营效率以及优化用户体验具有重要意义。本文将详细探讨电商 API 接口接入的关键技术要点&#xff0c;并结合实践经验为您提供一份实用的接入指南。 一、电商 API 接口概述 电商 API 接口是电商…

【文献阅读】Accou2vec: A Social Bot Detection Model Based on Community Walk

Abstract Accou2vec。首先&#xff0c;为了切断人类账户和机器人账户之间的攻击边&#xff0c;利用类似深度自动编码器的非负矩阵分解社区检测算法将社交图划分为多个子图。然后设计了社区漫游规则&#xff0c;分别控制社区内部和社区间的漫游&#xff0c;同时考虑社区中的节点…

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页--添加商品功能

技术支持&#xff1a;JAVA、JSP 服务器&#xff1a;TOMCAT 7.0.86 编程软件&#xff1a;IntelliJ IDEA 2021.1.3 x64 前文三篇登录和注册功能的实现 基于JSP、java、Tomcat、mysql三层交互的项目实战--校园交易网&#xff08;1&#xff09;-项目搭建&#xff08;前期准备工作…

cjson

文章目录 概述编译cjson_test 小结 概述 在网络传输中&#xff0c;网络数据序列化&#xff0c;常用的有那么几种&#xff0c;json&#xff0c;protobuf都是很常用的&#xff0c;这一篇来写下json。 Json常用的有几个&#xff0c;rapidjson&#xff0c;jsoncpp&#xff0c;还有…

HarmonyOS开发:路由容器Navigation的使用详解

​目录 前言路由容器NavigationNavigation组成路由跳转操作Navigation下的页面生命周期最后 前言 众所周知&#xff0c;HarmonyOS作为华为推出的新一代操作系统&#xff0c;其开发框架提供了全新的能力和组件&#xff0c;以支持跨平台应用开发&#xff0c;越来越多的开发者加…

红黑树实现详解

实践意义 在各方面&#xff0c;红黑树要比AVL树性能更好&#xff0c;用途也更广泛 map&set底层都主要靠红黑树 概念 性质 插入时&#xff0c;抽象图 cur为新插入 插入时颜色更新逻辑图 板书

bugku-web-never_give_up

解题思路 F12查看请求和响应&#xff0c;查找线索 相关工具 base64解码URL解码Burp Suit抓包 页面源码提示 <!--1p.html--> 2. 去访问这个文件&#xff0c;发现直接跳转到BUGKU首页&#xff0c;有猫腻那就下载看看这个文件内容吧 爬虫下载这个文件 import requests …

20240804 每日AI必读资讯

25亿独角兽CEO带头跑路&#xff0c;携30员工卖身谷歌&#xff01;AI大佬&#xff1a;AGI泡沫几周就要破 - CEO一并带走的&#xff0c;还有Character.AI负责模型训练和语音AI的员工&#xff0c;也就是130名员工中的30人。他们将加入谷歌&#xff0c;参与Gemini AI项目。 - Cha…

【C++学习第19天】二分图

一、如何判断一个图是二分图&#xff1f; 二、代码 1、判断是否为二分图 #include <iostream> #include <algorithm> #include <cstring>using namespace std;const int N 200010;int n, m; int h[N], e[N], ne[N], idx; int color[N];void add(int a, in…

JavaScript 继承百花齐放:从原型链到 ES6 类

前言 &#x1f4eb; 大家好&#xff0c;我是南木元元&#xff0c;热爱技术和分享&#xff0c;欢迎大家交流&#xff0c;一起学习进步&#xff01; &#x1f345; 个人主页&#xff1a;南木元元 在 JavaScript 中&#xff0c;继承是一个重要的知识点&#xff0c;上篇文章中我们已…

【Java】Java Swing 图书管借阅管理系统(源码+论文)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…