目前AI模型领域百家争鸣,尽管LangChain官方提供了一些接口,但是可能并不支持所有模型。如果你需要自定义模型并将其接入LangChain框架,这是一种可能的选择。刚好文心一言能力全面开放,本教程借助文心一言大模型讲解在LangChain如何自定义 LLM,点击查看《文心一言注册及调用教程》。 《LangChain 入门到实战教程》更多内容
自定义 LLM
自定义 LLM 需要实现以下必要的函数:
_call
:它需要接受一个字符串、可选的停用词,并返回一个字符串。
它还可以实现第二个可选的函数:
_identifying_params
:用于帮助打印 LLM 信息。该函数应该返回一个字典。
使用LLM模块来封装我们的模型接口,可以带来许多好处,其中之一就是有利于与LangChain的其他模块进行协同工作。
下面我们通过 LangChain自定义LLM 实现文心一言 ERNIE-Bot-turbo 大模型接入:
import json
import time
from typing import Any, List, Mapping, Optional, Dict, Union, Tuple
import logging
import requests
from langchain.callbacks.manager import CallbackManagerForLLMRun
from langchain.llms.base import LLM
from langchain.utils import get_from_dict_or_env
from pydantic import Field, root_validator
logger = 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 "请求失败"
使用自定义 LLM
配置及加载环境变量
在 .env 文件中配置变量:
ERNIE_API_KEY=******
ERNIE_SECRET_KEY=******
加载配置文件:
import dotenv
dotenv.load_dotenv('.env')
调用 LLM
最简单的调用:
from ErnieModel import ErnieLLm
llm = ErnieLLm()
print(llm("你是文心一言吗?"))
运行结果:
是的,我是文心一言。我能够与人对话互动,回答问题,协助创作,高效便捷地帮助人们获取信息、知识和灵感。
也可以通过构造直接传入 ernie_api_key
和ernie_secret_key
,如:
llm = ErnieLLm(ernie_api_key="******",ernie_secret_key="******")
LLM 关键参数
我们可以通过调整 temperature
、top_p
、penalty_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]
使用方法:
llm = ErnieLLm(temperature=0.99)
print(llm("给我讲一个笑话"))
llm = ErnieLLm(temperature=0.95, top_p=1.0)
print(llm("给我讲一个笑话"))
运行结果:
当然可以,这是一个关于两只熊的笑话:
有一天,一只熊从动物园里跑了出来,吓坏了的人们纷纷逃窜。但是,动物园的管理员很镇定,他决定去和熊谈判。他对熊说:“熊啊,我知道你是饿了,但是你也不能吃人啊。我们去动物园里吃竹子好不好?”熊想了想,觉得有道理,于是就答应了。
管理员带熊去了动物园的竹林,让熊吃了一顿丰盛的竹子大餐。熊很开心,于是问管理员:“你为什么知道我那么喜欢吃竹子呢?”管理员回答:“因为我是管理员啊。”
熊一脸懵逼地看着管理员,然后突然明白了什么,说:“原来你是个‘装熊’的家伙啊!”
好的,这里有一个笑话:
有天捡到一个神灯,灯神宣布可以许一个愿望。
我当即许愿:请赐予我一个美女相伴。
只见灯神拿出一个通关文牒,哗啦啦地翻了很多页,然后递给我说:抱歉,您的愿望尚未出现。
添加缓存
从之前的文章中我们讲过如何使用缓存以及多种缓存方式,在这里我们使用本地内存缓存,配置缓存后,如果同一个问题被第二次提问,模型可以快速给出答案。
from langchain.cache import InMemoryCache
# 启动llm的缓存
langchain.llm_cache = InMemoryCache()
由于在自定义LLM时,缓存参数 cache
默认为 False,这里我们需要设置为 True。同时我们通过两次执行来看看效果:
llm = ErnieLLm(temperature=0.95, top_p=1.0, cache=True)
s = time.perf_counter()
# 第一次调用
print(llm("给我讲一个笑话"))
elapsed = time.perf_counter() - s
print("\033[1m" + f"第一次调用耗时 {elapsed:0.2f} 秒." + "\033[0m")
s = time.perf_counter()
# 第一次调用
print(llm("给我讲一个笑话"))
elapsed = time.perf_counter() - s
print("\033[1m" + f"第二次调用耗时 {elapsed:0.2f} 秒." + "\033[0m")
运行结果:
当然可以,这是一个关于两只鸟的笑话:
有两只小鸟,一只小鸟问:“哥哥,人们都说你长得好帅,你觉得自己帅吗?”哥哥小鸟羞涩地回答:“不,我不觉得自己帅,我只是很可爱。”而第二只小鸟打断了他:“哥呀,人家说的是你旁边的蝴蝶卷毛哈。”
第一次调用耗时 2.37 秒.
当然可以,这是一个关于两只鸟的笑话:
有两只小鸟,一只小鸟问:“哥哥,人们都说你长得好帅,你觉得自己帅吗?”哥哥小鸟羞涩地回答:“不,我不觉得自己帅,我只是很可爱。”而第二只小鸟打断了他:“哥呀,人家说的是你旁边的蝴蝶卷毛哈。”
第二次调用耗时 0.00 秒.
可以看到第二次请求所用时间近乎为0(可能是纳秒级别)。
小结
本文主要介绍了在LangChain平台上自定义LLM的步骤和参数,并以文心一言的ERNIE-Bot-turbo模型为例进行了详细说明。文章首先介绍了自定义LLM需要实现的必要函数,包括_call
函数和_identifying_params
函数。然后,通过导入dotenv模块和配置环境变量,示例代码演示了如何加载配置文件并调用自定义LLM。接下来,文章介绍了LLM的一些关键参数,如temperature
、top_p
和penalty_score
,并展示了如何根据需要调整这些参数来优化模型的回答结果。最后,文章提到了使用缓存的方法,通过启动LLM的缓存来加速模型的响应速度,并通过两次调用的结果展示了缓存的效果。
零基础如何学习大模型 AI
领取方式在文末
为什么要学习大模型?
学习大模型课程的重要性在于它能够极大地促进个人在人工智能领域的专业发展。大模型技术,如自然语言处理和图像识别,正在推动着人工智能的新发展阶段。通过学习大模型课程,可以掌握设计和实现基于大模型的应用系统所需的基本原理和技术,从而提升自己在数据处理、分析和决策制定方面的能力。此外,大模型技术在多个行业中的应用日益增加,掌握这一技术将有助于提高就业竞争力,并为未来的创新创业提供坚实的基础。
大模型实际应用案例分享
①智能客服:某科技公司员工在学习了大模型课程后,成功开发了一套基于自然语言处理的大模型智能客服系统。该系统不仅提高了客户服务效率,还显著降低了人工成本。
②医疗影像分析:一位医学研究人员通过学习大模型课程,掌握了深度学习技术在医疗影像分析中的应用。他开发的算法能够准确识别肿瘤等病变,为医生提供了有力的诊断辅助。
③金融风险管理:一位金融分析师利用大模型课程中学到的知识,开发了一套信用评分模型。该模型帮助银行更准确地评估贷款申请者的信用风险,降低了不良贷款率。
④智能推荐系统:一位电商平台的工程师在学习大模型课程后,优化了平台的商品推荐算法。新算法提高了用户满意度和购买转化率,为公司带来了显著的增长。
…
这些案例表明,学习大模型课程不仅能够提升个人技能,还能为企业带来实际效益,推动行业创新发展。
学习资料领取
如果你对大模型感兴趣,可以看看我整合并且整理成了一份AI大模型资料包,需要的小伙伴文末免费领取哦,无偿分享!!!
vx扫描下方二维码即可
加上后会一个个给大家发
部分资料展示
一、 AI大模型学习路线图
整个学习分为7个阶段
二、AI大模型实战案例
涵盖AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,皆可用。
三、视频和书籍PDF合集
从入门到进阶这里都有,跟着老师学习事半功倍。
如果二维码失效,可以点击下方链接,一样的哦
【CSDN大礼包】最新AI大模型资源包,这里全都有!无偿分享!!!
😝朋友们如果有需要的话,可以V扫描下方二维码联系领取~