自定义 LLM:LangChain与文心一言擦出火花

自定义 LLM

自定义 LLM 需要实现以下必要的函数:

  • _call :它需要接受一个字符串、可选的停用词,并返回一个字符串。

它还可以实现第二个可选的函数:

  • _identifying_params :用于帮助打印 LLM 信息。该函数应该返回一个字典。

使用LLM模块来封装我们的模型接口,可以带来许多好处,其中之一就是有利于与LangChain的其他模块进行协同工作。

下面我们通过 LangChain自定义LLM 实现文心一言 ERNIE-Bot-turbo 大模型接入:

代码语言:javascript

复制

import jsonimport timefrom typing import Any, List, Mapping, Optional, Dict, Union, Tupleimport loggingimport requestsfrom langchain.callbacks.manager import CallbackManagerForLLMRunfrom langchain.llms.base import LLMfrom langchain.utils import get_from_dict_or_envfrom pydantic import Field, root_validatorlogger = logging.getLogger(__name__)def get_access_token(api_key: str, secret_key: str):    """    使用 API Key,Secret Key 获取access_token    """    url = f"https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id={api_key}&client_secret={secret_key}"    payload = json.dumps("")    headers = {        'Content-Type': 'application/json',        'Accept': 'application/json'    }    resp = requests.request("POST", url, headers=headers, data=payload)    return resp.json().get("access_token")class ErnieLLm(LLM):    url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/eb-instant"    model_name: str = Field(default="ERNIE-Bot-turbo", alias="model")    request_timeout: Optional[Union[float, Tuple[float, float]]] = None    temperature: float = 0.95    """temperature 说明:    (1)较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定    (2)默认0.95,范围 (0, 1.0],不能为0    (3)建议该参数和top_p只设置1个    (4)建议top_p和temperature不要同时更改    """    top_p: float = 0.8    """top_p 说明:    (1)影响输出文本的多样性,取值越大,生成文本的多样性越强    (2)默认0.8,取值范围 [0, 1.0]    (3)建议该参数和temperature只设置1个    (4)建议top_p和temperature不要同时更改    """    penalty_score: float = 1.0    """通过对已生成的token增加惩罚,减少重复生成的现象。说明:    (1)值越大表示惩罚越大    (2)默认1.0,取值范围:[1.0, 2.0]    """    ernie_api_key: Optional[str] = None    """文心一言大模型 apiKey"""    ernie_secret_key: Optional[str] = None    """文心一言大模型 secretKey"""    user_id: Optional[str] = None    """表示最终用户的唯一标识符,可以监视和检测滥用行为,防止接口恶意调用"""    streaming: bool = False    """是否以流式接口的形式返回数据,默认false"""    cache: bool = False    """是否开启缓存,默认为false"""    model_kwargs: Dict[str, Any] = Field(default_factory=dict)    """Holds any model parameters valid for `create` call not explicitly specified."""    @root_validator()    def validate_environment(cls, values: Dict) -> Dict:        """Validate that api key and python package exists in environment."""        values["ernie_api_key"] = get_from_dict_or_env(            values, "ernie_api_key", "ERNIE_API_KEY"        )        values["ernie_secret_key"] = get_from_dict_or_env(            values,            "ernie_secret_key",            "ERNIE_SECRET_KEY"        )        return values    @property    def _default_params(self) -> Dict[str, Any]:        """获取调用Ennie API的默认参数。"""        normal_params = {            "temperature": self.temperature,            "top_p": self.top_p,            "penalty_score": self.penalty_score,            "request_timeout": self.request_timeout,        }        return {**normal_params, **self.model_kwargs}    def _construct_query(self, prompt: str) -> Dict:        """构造请求体"""        query = {            "messages": [                {                    "role": "user",                    "content": prompt                }            ],            "stream": self.streaming,            "temperature": self.temperature,            "top_p": self.top_p,            "penalty_score": self.penalty_score,            "user_id": self.user_id,        }        return query    @property    def _identifying_params(self) -> Mapping[str, Any]:        """Get the identifying parameters."""        return {**{"model_name": self.model_name}, **self._default_params}    @property    def _llm_type(self) -> str:        return "ernie"    def _call(            self,            prompt: str,            stop: Optional[List[str]] = None,            run_manager: Optional[CallbackManagerForLLMRun] = None,            **kwargs: Any,    ) -> str:        """_call 实现对模型的调用"""        # construct query        query = self._construct_query(prompt=prompt)        # post        _headers = {"Content-Type": "application/json"}        with requests.session() as session:            resp = session.post(                self.url + "?access_token=" + get_access_token(self.ernie_api_key, self.ernie_secret_key),                json=query,                headers=_headers,                timeout=60)            if resp.status_code == 200:                resp_json = resp.json()                predictions = resp_json["result"]                return predictions        return "请求失败"

😝有需要的小伙伴,可以V扫描下方二维码免费领取🆓

### **使用自定义 LLM**
配置及加载环境变量

在 .env 文件中配置变量:

代码语言:javascript

复制

加载配置文件:

代码语言:javascript

复制

调用 LLM

最简单的调用:

代码语言:javascript

复制

运行结果:

代码语言:javascript

复制

也可以通过构造直接传入 ernie_api_keyernie_secret_key,如:

代码语言:javascript

复制

LLM 关键参数

我们可以通过调整 temperaturetop_ppenalty_score等参数来优化模型回答的结果。

temperature

说明: (1)较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定 (2)默认0.95,范围 (0, 1.0],不能为0 (3)建议该参数和top_p只设置1个 (4)建议top_p和temperature不要同时更改

top_p

说明: (1)影响输出文本的多样性,取值越大,生成文本的多样性越强 (2)默认0.8,取值范围 [0, 1.0] (3)建议该参数和temperature只设置1个 (4)建议top_p和temperature不要同时更改

penalty_score

通过对已生成的token增加惩罚,减少重复生成的现象。说明: (1)值越大表示惩罚越大 (2)默认1.0,取值范围:[1.0, 2.0]

使用方法:

代码语言:javascript

复制

运行结果:

代码语言:javascript

复制

添加缓存

从之前的文章中我们讲过如何使用缓存以及多种缓存方式,在这里我们使用本地内存缓存,配置缓存后,如果同一个问题被第二次提问,模型可以快速给出答案。

代码语言:javascript

复制

from langchain.cache import InMemoryCache# 启动llm的缓存langchain.llm_cache = InMemoryCache()

由于在自定义LLM时,缓存参数 cache默认为 False,这里我们需要设置为 True。同时我们通过两次执行来看看效果:

代码语言:javascript

复制

llm = ErnieLLm(temperature=0.95, top_p=1.0, cache=True)s = time.perf_counter()# 第一次调用print(llm("给我讲一个笑话"))elapsed = time.perf_counter() - sprint("\033[1m" + f"第一次调用耗时 {elapsed:0.2f} 秒." + "\033[0m")s = time.perf_counter()# 第一次调用print(llm("给我讲一个笑话"))elapsed = time.perf_counter() - sprint("\033[1m" + f"第二次调用耗时 {elapsed:0.2f} 秒." + "\033[0m")

运行结果:

代码语言:javascript

复制

当然可以,这是一个关于两只鸟的笑话:有两只小鸟,一只小鸟问:“哥哥,人们都说你长得好帅,你觉得自己帅吗?”哥哥小鸟羞涩地回答:“不,我不觉得自己帅,我只是很可爱。”而第二只小鸟打断了他:“哥呀,人家说的是你旁边的蝴蝶卷毛哈。”第一次调用耗时 2.37.当然可以,这是一个关于两只鸟的笑话:有两只小鸟,一只小鸟问:“哥哥,人们都说你长得好帅,你觉得自己帅吗?”哥哥小鸟羞涩地回答:“不,我不觉得自己帅,我只是很可爱。”而第二只小鸟打断了他:“哥呀,人家说的是你旁边的蝴蝶卷毛哈。”第二次调用耗时 0.00.

可以看到第二次请求所用时间近乎为0(可能是纳秒级别)。

小结

本文主要介绍了在LangChain平台上自定义LLM的步骤和参数,并以文心一言的ERNIE-Bot-turbo模型为例进行了详细说明。文章首先介绍了自定义LLM需要实现的必要函数,包括_call函数和_identifying_params函数。然后,通过导入dotenv模块和配置环境变量,示例代码演示了如何加载配置文件并调用自定义LLM。接下来,文章介绍了LLM的一些关键参数,如temperaturetop_ppenalty_score,并展示了如何根据需要调整这些参数来优化模型的回答结果。最后,文章提到了使用缓存的方法,通过启动LLM的缓存来加速模型的响应速度,并通过两次调用的结果展示了缓存的效果。

那么,我们该如何学习大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

一、大模型全套的学习路线

学习大型人工智能模型,如GPT-3、BERT或任何其他先进的神经网络模型,需要系统的方法和持续的努力。既然要系统的学习大模型,那么学习路线是必不可少的,下面的这份路线能帮助你快速梳理知识,形成自己的体系。

L1级别:AI大模型时代的华丽登场

L2级别:AI大模型API应用开发工程

L3级别:大模型应用架构进阶实践

L4级别:大模型微调与私有化部署

一般掌握到第四个级别,市场上大多数岗位都是可以胜任,但要还不是天花板,天花板级别要求更加严格,对于算法和实战是非常苛刻的。建议普通人掌握到L4级别即可。

以上的AI大模型学习路线,不知道为什么发出来就有点糊,高清版可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OpenStack入门体验及一键部署

OpenStack入门体验 技能目标: 了解云计算概念 了解OpenStack 了解OpenStack的构成 会OpenStack单机环境一键部署 从控制台认识OpenStack各项功能会 通过OpenStack控制台创建云主机 什么是云计算 云计算(cloudcomputing)是一种基于网络的超级计算模式&a…

Java老人护理上门服务类型系统小程序APP源码

🌸 老人上门护理服务系统:温暖与专业并存 🌸 一、🏠 走进老人上门护理服务系统 随着社会的快速发展,我们越来越关注老年人的生活质量。老人上门护理服务系统应运而生,它结合了现代科技与人性化服务&#…

redis序列化

文章目录 1、为什么要进行序列化操作?2、序列化方式2.1、自定义序列化2. 2、StringRedisTemplate(重点) 1、为什么要进行序列化操作? 不进行序列化向redis存入数据代码: SpringBootTest class RedisDemoApplicationT…

java反序列化---cc6链

目录 Transformer[]数组分析 链条代码跟进 ChainedTransformer.transform() LazyMap.get() TiedMapEntry.getValue() TiedMapEntry.hashCode() HashMap.hash() HashMap.put()的意外触发 LazyMap.get()中key的包含问题 cc6的payload如下 import org.apache.commons.co…

Vue40-vueComponent构造函数

一、组件的本质:VueComponent构造函数 组件的本质是:构造函数 二、每一次调用vue.extend,返回的事一个全新的 VueComponent VueComponent的源码如下: 三、组件中的this 组件中的this是VueComponent实例对象,结构和vm…

vite.config.js如何使用env的环境变量

了解下环境变量在vite中 官方文档走起 https://cn.vitejs.dev/guide/env-and-mode.html#env-variables-and-modes 你见到的.env,.env.production等就是放置环境变量的 官方文档说到.env.[mode] # 只在指定模式下加载,比如.env.development只在开发环境加载 至于为什么是deve…

前缀和算法:算法秘籍下的数据预言家

✨✨✨学习的道路很枯燥,希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一. 前缀和算法的介绍 二、前缀和例题 2.1 【模版】前缀和 2.2 【模板】二维前缀和 2.3 寻找数组的中间下标 2.4 除自身以外数组的乘积 2.5 和为k的子数组 2.6 和可被k整除的子数组 2.7 …

maven编译【-Dmaven.test.skip=true和-DskipTests=true的区别】

1、背景 我在执行maven编译时,遇到下面情况: 1、当执行命令为下面: mvn clean compile package install -Dmaven.wagon.http.ssl.insecuretrue -Dmaven.wagon.http.ssl.allowalltrue -Dmaven.wagon.http.ssl.ignore.validity.datestrue -Dra…

红队内网攻防渗透:内网渗透之Linux内网权限提升技术:udf提权Capability权限LD_PRELOAD环境变量

红队内网攻防渗透 1. 内网权限提升技术1.1 Linux系统提权-Web&用户-数据库udf提权1.1.1 信息收集1.1.2 Web权限获取1.1.3 MYSQL-UDF提权1.1.4 下载到目标上1.1.5 连接确认是否有条件进行导出调用1.1.6 开始进行写入导出调用1.2 Linux系统提权-Web&用户-Capability能力1…

Java语言+前端框架html+Thymeleaf +后端框架springboot开发的UWB智能定位系统源码 UWB三维可视化人员定位系统源码

Java语言前端框架htmlThymeleaf 后端框架springboot开发的UWB智能定位系统源码 UWB三维可视化人员定位系统源码 UWB定位系统基于B/S架构的软件和嵌入式硬件都具有很好的扩展性和兼容性,可以与其他系统接口(比如:围界、AB门、高压电网、报警、…

怎么图片转excel表格?推荐三个方法

怎么图片转excel表格?在信息化高速发展的今天,图片转Excel表格的需求日益凸显,尤其是在职场办公中,这一需求更是显得尤为迫切。为了满足广大用户的需求,市面上涌现出了众多图片转Excel的软件。今天,就为大家…

QT 使用资源文件的注意点

不要存放没有使用的资源文件 即使在代码中没有使用到的资源文件,也会编译到执行文件或者DLL里面去这样会增大它的体积。如下 在代码没有使用这个资源文件(10.4M的2k图片),但是编译出来的程序有 12M左右的大小

java写一个验证码

生成验证码 内容:可以是小写字母,也可以是大写字母,还可以是数字 规则 长度为5 内容中是四位字母,1位数字。 其中数字只有1位,但是可以出现在任意的位置。 package User;import java.util.ArrayList; import jav…

Android Studio Jellyfish版本修改project使用特定jdk版本的步骤

android studio总是把这些东西改来改去让人十分恼火,IDE本身改来改去就让人无法上手就立即工作,很多时间浪费在IDE和gradle的配置和奇奇怪怪现象的斗智斗勇上,搞Android是真的有点浪费生命。一入此坑深不见底 jellyfish版安卓studio已经无法通…

LeetCode | 434.字符串中的单词数

这道题直接使用语言内置的 split 函数可直接分离出字符串中的每个单词,但是要注意区分两种情况:1、空串;2、多个空格连续,分割后会出现空字符的情况,应该舍弃 class Solution(object):def countSegments(self, s):&qu…

接口测试之用Fiddler对手机app进行抓包

Fiddler是一款非常流行并且实用的http抓包工具,它的原理是在本机开启了一个http的代理服务器,然后它会转发所有的http请求和响应,因此,它比一般的firebug或者是chrome自带的抓包工具要好用的多。不仅如此,它还可以支持…

202478读书笔记|《人间小满》——小满,才是最好的人生状态,养身先养心,知世故而不世故,历圆滑而弥天真

202478读书笔记|《人间小满》——小满,才是最好的人生状态,养身先养心,知世故而不世故,历圆滑而弥天真 一、画出世俗的欢喜,过一种平淡自由的人生二、与时舒卷,抵岁月荒唐三、一半是海水,一半是…

案例学习-存量更新规划实施探索(武汉)

案例学习-存量更新规划实施探索(武汉) 武汉市在早期旧城更新实践中发现零散化的更新往往导致资源配置分散、城市建设破碎化等弊病,特别是由于过于强调项目自身“经济平衡”,在实施过程中也逐步暴露出住宅占比过大、强度偏高、公服…

C++之模板

在C 中&#xff0c;模板为泛型程序设计奠定了关键的基础。使用模板需要用到两个关键字template 、typename&#xff0c;写法&#xff1a;template<typename Type> template告诉编译器&#xff0c;将要定义一个模板&#xff0c;<>中的是模板参数列表&#xff0c;类…

AGI 远不止 ChatGPT!一文入门 AGI 通识及应用开发

AI 大语言模型进入爆发阶段 2022 年 12 月 ChatGPT 突然爆火&#xff0c;原因是其表现出来的智能化已经远远突破了我们的常规认知。虽然其呈现在使用者面前仅仅只是一个简单的对话问答形式&#xff0c;但是它的内容化水平非常强大&#xff0c;甚至在某些方面已经超过人类了&am…