怎么做网站推广平台,浮动播放器wordpress,石家庄企业建站,静安微信手机网站制作1 模型部署
定义#xff1a;
在软件工程中#xff0c;部署通常指的是将开发完毕的软件投入使用的过程。在人工智能领域#xff0c;模型部署是实现深度学习算法落地应用的关键步骤。简单来说#xff0c;模型部署就是将训练好的深度学习模型在特定环境中运行的过程。
场景…1 模型部署
定义
在软件工程中部署通常指的是将开发完毕的软件投入使用的过程。在人工智能领域模型部署是实现深度学习算法落地应用的关键步骤。简单来说模型部署就是将训练好的深度学习模型在特定环境中运行的过程。
场景:
服务器端CPU部署单GPU/TPU/NPU部署多卡/集群 部署.移动端边缘端移动机器人手机……
2 大模型缓存推理技术
在大模型中Transformer模型扮演着至关重要的角色。它通过自注意力机制Self-Attention来捕捉文本中的上下文信息实现对文本的深入理解和推理。这种机制允许模型在处理每个token时都考虑到整个输入序列的上下文信息从而提高了模型的表达能力和准确性。
对于新的请求Query需要与历史的Key、Value计算注意力分数。如果每次都重新计算历史的Key、Value会浪费大量计算资源。每轮新迭代时将Key、Value进行缓存共下次迭代使用。
KV Cache的全称是key-value cache可以简单理解为对大模型推理过程中的key-value缓存的优化。
LMDeploy 对 KV Cache 的实现:
预先申请策略减少运行时因申请/释放内存的消耗时间。通过设置cache_max_entry_count参数来调节 KV Cache 占用内存的大小为占用剩余显存的比例。
下图0.2表示KV Cache 可以占用的显存大小是在加载玩模型权重后所剩余的显存的20%。
3 大模型量化技术
量化技术将传统的表示方法中的浮点数转换为整数或其他离散形式以减轻深度学习模型的存储和计算负担。
为什么要做量化
提升推理的速度增加上下文长度速度更快的kernel降低I/0延迟降低推理成本
量化思路将原来浮点数所在区间做一个线性映射映射为一些列整数。以 INT8 的8位二进制数为例通用公式 Z P min max 2 量化: q r o u n d ( f − Z P S ) S max − min 255 反量化: f q × S Z P ZP\frac{\min\max} {2} \quad\text{量化:} \, q\mathrm{round}\left(\frac{f-ZP}{S}\right) \\ S\frac{\max-\min}{255}\quad \text{反量化:} \, fq\times SZP ZP2minmax量化:qround(Sf−ZP)S255max−min反量化:fq×SZP 量化方法的分类 1按量化对象分
KV Cache量化模型权重量化激活值量化 (例如对于一个线性层 y w x y wx ywx 中 w w w为权重 x x x为激活值)
2按量化阶段分
量化感知训练QAT量化感知微调QAF)训练后量化PTQ训练好模型后在完成量化常用这种方式
由于QAT和QAF一般在模型训练后仍然需要做微调操作量化通常不采用这两种方式。
3.1 LMDeploy 量化方案
LMDeploy 量化方式KV Cache量化 模型权重量化 训练后量化
3.1.1 KV Cache量化
在线KVCacheINT4/INT8量化粒度为 per-head per-token与FP16相比INT4/INT8的KVBlock数量分别可以提升4倍和2倍。意义更长的上下文、更高的并发吞吐精度上INT8几乎无损INT4略有损失 3.1.2 模型权重量化(W4A16量化)
基于 AWQ 算法对权重进行4bit量化计算时返量化使用FP16性能是FP16的2.4倍以上权重大小、显存降为FP16的的1/4
3.1.3 AWQ 量化原理**
参考论文AWQ
核心观点1权重并不等同重要仅有0.1~1%小部分显著权重对推理结果影响较大。
如果有办法将这0.1~1%的小部分显著权重保持FP16对其他权重进行低比特量化可以大幅降低内存占用。那么问题来了如果选出显著权重 1随机挑选听天由命 2基于权重分布挑选好像应该这样 3基于激活值挑选竟然是这样
AWQ 论文对三者做了实验对比返实验结果表明基于激活值挑选显著权重效果显著。 基于激活值按通道“组团”挑选显著权重权重。为了避免实现上过于复杂在挑选显著权重时并非在“元素”级别进行挑选而是在“通道”级别进行挑选。 首先将激活值对每一列channel求绝对值的平均值把平均值较大一列对应的通道视作显著权重。 但是随之伴随问题
显著权重INT4非显著权重FP16“显著”的阈值如何实现一个通道粒度上混合精度的kernel这是硬件不友好的行为这更是开发者不友好的行为
核心观点2量化前对显著权重进行放大可以降低量化误差。
考虑权重矩阵w线性运算写作ywx。对权重矩阵进行量化后可以写作yQw)x。Q·)定义如下实验表现
随着s增大假设成立的概率越来越低但在s2之前概率还是很低的5%)在一定范围内随着s的增大误差比值越来越小完全支持作者观点
所有权重均低比特量化。显著权重乘以较大s等效于降低量化误差。非显著权重乘以较小的s等效于给予更少的关注。 LMDeploy 采用分组计算每个通道的缩放系数 4 大模型外推技术
大模型长度外推性是一个训练和预测的长度不一致的问题。
外推引发的两大问题
预测阶段用到了没训练过的位置编码 模型不可避免地在一定程度上对位置编码“过拟合”预测注意力时注意力机制所处理的token数量远超训练时的数量 导致计算注意力“熵”的差异较大
4.1 为什么需要位置编码
因为并行化的自注意力机制并不具备区分token相对位置的能力。位置编码用于为输入序列的每个位置添加一种表示其位置信息的编码。通过引入位置编码Transformer模型可以更好地捕捉序列中不同位置之间的关系从而更好地处理长距离依赖关系。 如果直接使用一个整数作为位置信息提供给模型则会造成数值跨度过大对梯度优化器不友好模型学习困难。 如果将数值缩放到 [0-1] 区间则会造成数值跨度过小模型和优化器都难以分辨位置。 使用向量表示位置: “10进制”为例位置1234可以用4维向量[1 2 3 4]表示。一般地位置N可以用如下向量表示 ∣ N 1 0 3 ∣ m o d 10 ∣ N 1 0 2 ∣ m o d 10 ∣ N 1 0 2 ∣ m o d 10 ∣ N 1 0 0 ∣ m o d 10 \left|\frac{N}{10^{3}}\right|\mathrm{mod}10\quad\left|\frac{N}{10^{2}}\right|\mathrm{mod}10\quad\left|\frac{N}{10^{2}}\right|\mathrm{mod}10\quad\left|\frac{N}{10^{0}}\right|\mathrm{mod}10 103N mod10 102N mod10 102N mod10 100N mod10 更一般地果不是10进制是β进制呢第i位数是为 ⌊ N β i ⌋ m o d β \left\lfloor\frac{N}{\beta^i}\right\rfloor\mathrm{mod~}\beta ⌊βiN⌋mod β 这里的取余重在表示周期性。
Transformer使用的 Sinusoidal 位置编码 p i , 2 j sin ( i 1000 0 2 j / d ) , p i , 2 j 1 cos ( i 1000 0 2 j / d ) p_{i,2j}\sin\left(\frac i{10000^{2j/d}}\right),\quad p_{i,2j1}\cos\left(\frac i{10000^{2j/d}}\right) pi,2jsin(100002j/di),pi,2j1cos(100002j/di)
mod”的主要特性是周期性因此与周期函数cos/sin具有一定的等效性因此Sinusoidal 位置编码可以认为是一种特殊的β进制编码
4.2 从位置编码角度解决外推引发的问题
方案训练阶段就预留好足够的位数
Transformer的原作者就是这么想的认为预留好位数后模型就能具备对位置编码的泛化性。 现实情况模型并没有按照我们的期望进行泛化训练阶段大多数高位都是“0”因此这部分位数没有被充分训练模型无法处理这些新编码。
线性内插法
方案把“新长度范围”等比例缩放至训练阶段的长度范围。如训练时使用1k训练需外推至4k就将 [04k] 的范围线性缩放至 [01k]。 n / k β d / 2 − 1 \frac{n/k}{\beta^{d/2-1}} βd/2−1n/k 但是这会使最低位非常“拥挤”通常需要进行微调使模型适应拥挤的映射关系。各维度差异较大其他位置差异为1个位差异较小模型不易分辨效果不佳。
进制转换法
大模型其实并不知道我们输入的位置编码具体是多少“进制”的他只对相对大小关系敏感能否通过“进制转换”来等效“内插” 如10进制下3位表示范围是0~99916进制下3位表示范围是0 ~ FFFFFF164095 虽然每一位上都有可能出现大于“9”的数但相对大小差异仍为“1”模型有能力进行泛化。把内插的压力平均分摊到了每一位上。
4.2.1 NTK-aware 外推技术
预测阶段计算系数对位置编码的底数base进行缩放使得与线性内插法值相等 n ( β λ ) d / 2 − 1 n / k β d / 2 − 1 \frac{n}{(\beta\lambda)^{d/2-1}}\frac{n/k}{\beta^{d/2-1}} (βλ)d/2−1nβd/2−1n/k n 是实际预测长度k 是实际长度与训练长度的比值。求得 λ k 2 / ( d − 2 ) \lambdak^{2/(d-2)} λk2/(d−2)
可得位置编码为 sin ( n ( β λ ) i ) sin ( n ( θ 2 / d k 2 / ( d − 2 ) ) i ) sin ( n ( θ k d / ( d − 2 ) ) 2 i ) \sin\left(\frac{n}{(\beta\lambda)^{i}}\right)\sin\left(\frac{n}{(\theta^{2/d}k^{2/(d-2)})^{i}}\right)\sin\left(\frac{n}{(\theta k^{d/(d-2)})^{2i}}\right) sin((βλ)in)sin((θ2/dk2/(d−2))in)sin((θkd/(d−2))2in)
5 Function Calling
什么是Function Calling为什么要有FunctionCalling
FunctionCalling即为让LLM调用外部函数解决问题从而拓展LLM的能力边界。
指的是在语言模型中集成外部服务或API的调用能力。模型可以在生成文本的过程中调用外部函数或服务获取额外的数据或执行特定的任务。
Function Calling的意义
解决时效性问题 今天是哪年哪日今天天气如何拓展LLM能力边界 帮我算一下 e 8 / 12345 e^8/12345 e8/12345 等于多少帮我搜索一下这篇论文
5.1 Function Calling 与 RAG
工作原理
Function Calling 指的是在语言模型中集成外部功能或API的调用能力 模型可以在生成文本的过程中调用外部函数或服务获取额外的数据或执行特定的任务。RAG 结合了信息检索和文本生成 它首先从一个大型的文档数据库中检索与输入查询相关的文档然后将这些文档的信息融入到语言模型的生成过程中。
应用场景
Function Calling 适用于需要模型执行特定操作或与外部系统交互的场景。 例如模型可以调用天气API来回答关于当前天气的问题或者调用翻译服务来提供翻译 在动态数据查询、任务自动化、系统集成以及结构化数据获取等方面有广泛应用。RAG 适用于那些需要外部信息来提供准确回答的场景 如问答系统它可以通过检索到的信息来丰富和支模型的回答 在医疗、法律、研究等领域使用RAG可以保证提供的答案与权威文献一致。
6 LMDeploy 量化部署实践
6.1 配置LMDeploy环境
6.1.1 环境搭建
创建一个名为lmdeploy的conda环境python版本为3.10创建成功后激活环境并安装0.5.3版本的lmdeploy及相关包。
conda create -n lmdeploy python3.10 -y
conda activate lmdeploy
conda install pytorch2.1.2 torchvision0.16.2 torchaudio2.1.2 pytorch-cuda12.1 -c pytorch -c nvidia -y
pip install timm1.0.8 openai1.40.3 lmdeploy[all]0.5.3pip install datasets2.19.26.1.2 InternStudio 环境获取模型
InternStudio统一把模型放置在/root/models/目录。 运行以下命令创建文件夹并设置开发机共享目录的软链接。
mkdir /root/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-7b-chat /root/models
ln -s /root/share/new_models/Shanghai_AI_Laboratory/internlm2_5-1_8b-chat /root/models
ln -s /root/share/new_models/OpenGVLab/InternVL2-26B /root/models本实战使用internlm2_5-7b-chat和InternVL2-26B作为演示。由于上述模型量化会消耗大量时间(约8h)量化请使用internlm2_5-1_8b-chat模型完成。
6.1.3 LMDeploy 验证启动模型文件
在量化工作正式开始前我们还需要验证一下获取的模型文件能否正常工作以免竹篮打水一场空。
让我们进入创建好的conda环境并启动InternLM2_5-1_8b-chat
conda activate lmdeploy
lmdeploy chat /root/models/internlm2_5-7b-chat启动成功后可以提问:
启动大模型后查看资源监控 现在显存占用约23GB。
我们要运行参数量为7B的InternLM2.5由InternLM2.5的码仓查询InternLM2.5-7b-chat的config.json文件可知该模型的权重被存储为bfloat16格式 对于一个7B70亿参数的模型每个参数使用16位浮点数等于 2个 Byte表示则模型的权重大小约为 7×10^9 parameters×2 Bytes/parameter14GB 为什么现在显存占用约23GB呢 这是因为LMDeploy设置了kv cache量化占剩余显存的80% 此时对于24GB的显卡即30%A100权重占用14GB显存剩余显存24-1410GB因此kv cache占用10GB*0.88GB加上原来的权重14GB总共占用14822GB。 实际加载模型后其他项也会占用部分显存因此剩余显存比理论偏低实际占用会略高于22GB。
6.2 LMDeploy与InternLM2.5
前面我们直接在本地部署InternLM2.5。而在实际应用中我们有时会将大模型封装为API接口服务供客户端访问。
6.2.1 LMDeploy API部署InternLM2.5
启动API服务器 首先让我们进入创建好的conda环境并通下命令启动API服务器部署InternLM2.5模型
conda activate lmdeploy
lmdeploy serve api_server \/root/models/internlm2_5-7b-chat \--model-format hf \--quant-policy 0 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1命令解释
lmdeploy serve api_server这个命令用于启动API服务器。/root/models/internlm2_5-7b-chat这是模型的路径。--model-format hf这个参数指定了模型的格式。hf代表“Hugging Face”格式。--quant-policy 0这个参数指定了量化策略。--server-name 0.0.0.0这个参数指定了服务器的名称。在这里0.0.0.0是一个特殊的IP地址它表示所有网络接口。--server-port 23333这个参数指定了服务器的端口号。在这里23333是服务器将监听的端口号。--tp 1这个参数表示并行数量GPU数量。
这一步由于部署在远程服务器上所以本地需要做一下ssh转发才能直接访问。在你本地打开一个cmd或powershell窗口输入命令如下 ssh -CNg -L 23333:127.0.0.1:23333 rootssh.intern-ai.org.cn -p 你的ssh端口号打开浏览器访问http://127.0.0.1:23333看到如下界面即代表部署成功:
6.2.2 以命令行形式连接API服务器
关闭http://127.0.0.1:23333网页但保持终端和本地窗口不动新建一个终端。
conda activate lmdeploy
lmdeploy serve api_client http://localhost:23333稍待片刻等出现double enter to end input 的输入提示即启动成功此时便可以随意与InternLM2.5对话同样是两下回车确定输入exit退出。
6.2.3 以Gradio网页形式连接API服务器
保持启动23333端口的服务在新建终端中输入exit退出。
输入以下命令使用Gradio作为前端启动网页:
lmdeploy serve gradio http://localhost:23333 \--server-name 0.0.0.0 \--server-port 6006启动后关闭之前的cmd/powershell窗口重开一个再次做一下ssh转发(因为此时端口不同)。在你本地打开一个cmd或powershell窗口输入命令如下。
ssh -CNg -L 6006:127.0.0.1:6006 rootssh.intern-ai.org.cn -p 你的ssh端口号打开浏览器访问地址http://127.0.0.1:6006然后就可以与模型尽情对话了
6.3 LMDeploy Lite
随着模型变得越来越大我们需要一些大模型压缩技术来降低模型部署的成本并提升模型的推理性能。LMDeploy 提供了权重量化和 k/v cache两种策略。
6.3.1 设置最大kv cache缓存大小
kv cache是一种缓存技术通过存储键值对的形式来复用计算结果以达到提高性能和降低内存消耗的目的。在大规模训练和推理中kv cache可以显著减少重复计算量从而提升模型的推理速度。理想情况下kv cache全部存储于显存以加快访存速度。
模型在运行时占用的显存可大致分为三部分模型参数本身占用的显存、kv cache占用的显存以及中间运算结果占用的显存。LMDeploy的kv cache管理器可以通过设置--cache-max-entry-count参数控制kv缓存占用剩余显存的最大比例。默认的比例为0.8。
6.3.2 设置在线 kv cache int4/int8 量化
自 v0.4.0 起LMDeploy 支持在线 kv cache int4/int8 量化量化方式为 per-head per-token 的非对称量化。此外通过 LMDeploy 应用 kv 量化非常简单只需要设定 quant_policy 和cache-max-entry-count参数。目前LMDeploy 规定 quant_policy4 表示 kv int4 量化quant_policy8 表示 kv int8 量化。
例如输入以下指令启动API服务器
lmdeploy serve api_server \/root/models/internlm2_5-7b-chat \--model-format hf \--quant-policy 4 \--cache-max-entry-count 0.4\--server-name 0.0.0.0 \--server-port 23333 \--tp 1相比使用BF16精度的kv cacheint4的Cache可以在相同4GB的显存下只需要4位来存储一个数值而BF16需要16位。这意味着int4的Cache可以存储的元素数量是BF16的四倍。
6.3.3 W4A16 模型量化和部署
W4这通常表示权重量化为4位整数int4。这意味着模型中的权重参数将从它们原始的浮点表示例如FP32、BF16或FP16Internlm2.5精度为BF16转换为4位的整数表示。这样做可以显著减少模型的大小。A16这表示激活或输入/输出仍然保持在16位浮点数例如FP16或BF16。激活是在神经网络中传播的数据通常在每层运算之后产生。
使用1.8B模型进行量化
lmdeploy lite auto_awq \/root/models/internlm2_5-1_8b-chat \--calib-dataset ptb \--calib-samples 128 \--calib-seqlen 2048 \--w-bits 4 \--w-group-size 128 \--batch-size 1 \--search-scale False \--work-dir /root/models/internlm2_5-1_8b-chat-w4a16-4bit命令解释
lmdeploy lite auto_awq: lite这是LMDeploy的命令用于启动量化过程而auto_awq代表自动权重量化auto-weight-quantization。/root/models/internlm2_5-7b-chat: 模型文件的路径。--calib-dataset ptb: 这个参数指定了一个校准数据集这里使用的是’ptb’Penn Treebank一个常用的语言模型数据集。--calib-samples 128: 这指定了用于校准的样本数量—128个样本--calib-seqlen 2048: 这指定了校准过程中使用的序列长度—2048--w-bits 4: 这表示权重weights的位数将被量化为4位。--work-dir /root/models/internlm2_5-7b-chat-w4a16-4bit: 这是工作目录的路径用于存储量化后的模型和中间结果。
等终端输出如下时说明正在推理中稍待片刻: 报错解决
如果此处出现报错TypeError: NoneType object is not callable。原因datasets3.0 无法下载calibrate数据集解决办法pip install datasets2.19.2
等待推理完成便可以直接在你设置的目标文件夹看到对应的模型文件。
那么推理后的模型和原本的模型区别在哪里呢最明显的两点是模型文件大小以及占据显存大小。
我们可以输入如下指令查看在当前目录中显示所有子目录的大小
cd /root/models/
du -sh *输出结果如下(其余文件夹都是以软链接的形式存在的不占用空间故显示为0):
那么原模型大小呢输入以下指令查看。
cd /root/share/new_models/Shanghai_AI_Laboratory/
du -sh *那么显存占用情况对比呢
输入以下指令启动量化后的模型:
lmdeploy chat /root/models/internlm2_5-7b-chat --cache-max-entry-count 0.4显存占用情况
对于修改kv cache默认占用之前即如1.3 LMDeploy验证启动模型文件所示直接启动模型的显存占用情况(23GB)
在 BF16 精度下7B模型权重占用14GB70×10^9 parameters×2 Bytes/parameter14GBkv cache占用8GB剩余显存24-1410GBkv cache默认占用80%即10*0.88GB其他项1GB
故23GB权重占用14GBkv cache占用8GB其它项1GB
对于修改kv cache占用之后的显存占用情况(19GB)
bfloat16是16位的浮点数格式占用2字节16位的存储空间。int4是4位的整数格式占用0.5字节4位的存储空间。因此从bfloat16到int4的转换理论上可以将模型权重的大小减少到原来的1/4即7B个int4参数仅占用3.5GB的显存。kv cache占用16.4GB剩余显存24-3.520.5GBkv cache默认占用80%即20.5*0.816.4GB其他项约为1GB
故20.9GB权重占用3.5GBkv cache占用16.4GB其它项1GB
6.3.4 W4A16 量化 KV cacheKV cache 量化
输入以下指令让我们同时启用量化后的模型、设定kv cache占用和kv cache int4量化
lmdeploy serve api_server \/root/models/internlm2_5-1_8b-chat-w4a16-4bit \--model-format awq \--quant-policy 4 \--cache-max-entry-count 0.4\--server-name 0.0.0.0 \--server-port 23333 \--tp 1显存占用11.3GB 7 LMDeploy之FastAPI与Function call
7.1 API开发
与之前一样让我们进入创建好的conda环境并输入指令启动API服务器
conda activate lmdeploy
lmdeploy serve api_server \/root/models/internlm2_5-1_8b-chat-w4a16-4bit \--model-format awq \--cache-max-entry-count 0.4 \--quant-policy 4 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1保持终端窗口不动新建一个终端新建文件:
touch /root/internlm2_5.py写内容
# 导入openai模块中的OpenAI类这个类用于与OpenAI API进行交互
from openai import OpenAI# 创建一个OpenAI的客户端实例需要传入API密钥和API的基础URL
client OpenAI(api_keyYOUR_API_KEY, # 替换为你的OpenAI API密钥由于我们使用的本地API无需密钥任意填写即可base_urlhttp://0.0.0.0:23333/v1 # 指定API的基础URL这里使用了本地地址和端口
)# 调用client.models.list()方法获取所有可用的模型并选择第一个模型的ID
# models.list()返回一个模型列表每个模型都有一个id属性
model_name client.models.list().data[0].id# 使用client.chat.completions.create()方法创建一个聊天补全请求
# 这个方法需要传入多个参数来指定请求的细节
response client.chat.completions.create(modelmodel_name, # 指定要使用的模型IDmessages[ # 定义消息列表列表中的每个字典代表一个消息{role: system, content: 你是一个友好的小助手负责解决问题.}, # 系统消息定义助手的行为{role: user, content: 帮我讲述一个关于狐狸和西瓜的小故事}, # 用户消息询问时间管理的建议],temperature0.8, # 控制生成文本的随机性值越高生成的文本越随机top_p0.8 # 控制生成文本的多样性值越高生成的文本越多样
)# 打印出API的响应结果
print(response.choices[0].message.content)执行代码
conda activate lmdeploy
python /root/internlm2_5.py终端会输出如下结果
此时代表我们成功地使用本地API与大模型进行了一次对话如果切回第一个终端窗口会看到如下信息这代表其成功的完成了一次用户问题GET与输出POST
7.2 Function call
关于Function call即函数调用功能它允许开发者在调用模型时详细说明函数的作用并使模型能够智能地根据用户的提问来输入参数并执行函数。完成调用后模型会将函数的输出结果作为回答用户问题的依据。
首先让我们进入创建好的conda环境并启动API服务器。
启动服务
conda activate lmdeploy
lmdeploy serve api_server \/root/models/internlm2_5-7b-chat \--model-format hf \--quant-policy 0 \--server-name 0.0.0.0 \--server-port 23333 \--tp 1让我们使用一个简单的例子作为演示。输入如下指令新建internlm2_5_func.py写入内容
from openai import OpenAIdef add(a: int, b: int):return a bdef mul(a: int, b: int):return a * btools [{type: function,function: {name: add,description: Compute the sum of two numbers,parameters: {type: object,properties: {a: {type: int,description: A number,},b: {type: int,description: A number,},},required: [a, b],},}
}, {type: function,function: {name: mul,description: Calculate the product of two numbers,parameters: {type: object,properties: {a: {type: int,description: A number,},b: {type: int,description: A number,},},required: [a, b],},}
}]
messages [{role: user, content: Compute (35)*2}]client OpenAI(api_keyYOUR_API_KEY, base_urlhttp://0.0.0.0:23333/v1)
model_name client.models.list().data[0].id
response client.chat.completions.create(modelmodel_name,messagesmessages,temperature0.8,top_p0.8,streamFalse,toolstools)
print(response)
func1_name response.choices[0].message.tool_calls[0].function.name
func1_args response.choices[0].message.tool_calls[0].function.arguments
func1_out eval(f{func1_name}(**{func1_args}))
print(func1_out)messages.append({role: assistant,content: response.choices[0].message.content
})
messages.append({role: environment,content: f35{func1_out},name: plugin
})
response client.chat.completions.create(modelmodel_name,messagesmessages,temperature0.8,top_p0.8,streamFalse,toolstools)
print(response)
func2_name response.choices[0].message.tool_calls[0].function.name
func2_args response.choices[0].message.tool_calls[0].function.arguments
func2_out eval(f{func2_name}(**{func2_args}))
print(func2_out)执行代码
python /root/internlm2_5_func.py输出结果 我们可以看出InternLM2.5将输入Compute (35)*2根据提供的function拆分成了加和乘两步第一步调用function add实现加再于第二步调用function mul实现乘再最终输出结果16