如何构建检索增强生成聊天机器人

在 AI 不断发展的世界中,本地模型已成为关注的焦点,尤其是在隐私和安全方面具有优势。使用本地模型部署和开发聊天机器人的能力对于数据安全、隐私和成本管理特别有价值。Mistral 和 Llama2 成为两个表现最佳的开源本地大型语言模型 (LLM)。
Meta 在今年 7 月推出的 Llama2 是一个最先进的 LLM 集合。它提供了 70 亿、130 亿和 700 亿参数模型,所有这些模型都可免费用于研究和商业用途。Mistral AI 在 9 月发布的 Mistral 7B 被认为是同等大小的最强大 LLM。它在所有基准测试中都优于 Llama2 13B,即使它的参数更少,因此速度更快,更容易使用。
利用这两个基础模型以及来自开源项目 Panel 的聊天界面,我们将向您展示使用本地模型构建 AI 聊天机器人是多么容易。
在这篇文章中,您将学习如何
在开始之前,您需要安装 panel==1.3、ctransformers 和 langchain。请注意,如果您使用的是 Nvidia GPU,请安装 ctransformers[cuda]。
现在您已准备好!
让我们从 GGUF 量化版本的 Mistral 7B Instruct 开始,并使用 AutoClasses 中的 `AutoModelForCausalLM` 之一来加载模型。AutoClasses 可以帮助我们根据模型路径自动检索模型。AudoModelForCausalLM 是具有因果语言建模功能的模型类别之一,这是我们 Mistral 7B Instruct 模型所需的。
# Source: https://hugging-face.cn/TheBloke/Mistral-7B-Instruct-v0.1-GGUF
from ctransformers import AutoModelForCausalLM
# Set gpu_layers to the number of layers to offload to GPU. Set to 0 if no GPU acceleration is available on your system.
llm = AutoModelForCausalLM.from_pretrained("TheBloke/Mistral-7B-Instruct-v0.1-GGUF", model_file="mistral-7b-instruct-v0.1.Q4_K_M.gguf", model_type="mistral", gpu_layers=50)
print(llm("AI is going to"))
在上面的示例中,当我们运行模型推理时,它在整个答案生成后返回一个单一的响应。当我们生成长响应时,这可能会很慢。而且,当我们在聊天界面中时,看到模型一次一个词地“键入”响应可能更自然。这就是为什么我们有时可能希望在生成响应时“流式传输”响应。为此,我们只需在调用模型时添加 `stream=True`。
为了加快模型响应速度,我们使用 `async` 来允许 IO 任务在后台进行,以便计算机可以在等待模型响应时执行其他任务。
from ctransformers import AutoModelForCausalLM
async def callback(contents: str):
llms = {}
if "mistral" not in llms:
llms["mistral"] = AutoModelForCausalLM.from_pretrained(
"TheBloke/Mistral-7B-Instruct-v0.1-GGUF",
model_file="mistral-7b-instruct-v0.1.Q4_K_M.gguf",
gpu_layers=1,
)
llm = llms["mistral"]
response = llm(contents, stream=True, max_new_tokens=1000)
message = ""
for token in response:
message += token
yield message
`回调` 函数的结果是一个异步生成器,它允许我们迭代异步到达的数据。如果我们打印出这些值,我们可以看到响应令牌是如何一次一个地生成的。
如何将此模型包装到聊天界面中?Panel 使构建聊天机器人变得超级容易,只需五行代码即可!
注意:不需要异步回调,但它确实可以改善用户体验。
如果您有兴趣了解如何使用 OpenAI API 和 LangChain 构建 AI 聊天机器人,请查看我们之前的博客文章。
"""
Demonstrates how to use the ChatInterface widget to create a chatbot using
Mistral thru CTransformers.
"""
import panel as pn
from ctransformers import AutoModelForCausalLM
pn.extension()
async def callback(contents: str, user: str, instance: pn.chat.ChatInterface):
if "mistral" not in llms:
instance.placeholder_text = "Downloading model; please wait..."
llms["mistral"] = AutoModelForCausalLM.from_pretrained(
"TheBloke/Mistral-7B-Instruct-v0.1-GGUF",
model_file="mistral-7b-instruct-v0.1.Q4_K_M.gguf",
gpu_layers=1,
)
llm = llms["mistral"]
response = llm(contents, stream=True, max_new_tokens=1000)
message = ""
for token in response:
message += token
yield message
llms = {}
chat_interface = pn.chat.ChatInterface(callback=callback, callback_user="Mistral")
chat_interface.send(
"Send a message to get a reply from Mistral!", user="System", respond=False
)
chat_interface.servable()
我们可以添加来自另一个模型的响应吗?我们可以比较不同模型的响应吗?是的,我们绝对可以!这是一个例子
"""
Demonstrates how to use the ChatInterface widget to create a chatbot using
Llama2 and Mistral.
"""
import panel as pn
from ctransformers import AutoModelForCausalLM
pn.extension()
MODEL_ARGUMENTS = {
"llama": {
"args": ["TheBloke/Llama-2-7b-Chat-GGUF"],
"kwargs": {"model_file": "llama-2-7b-chat.Q5_K_M.gguf"},
},
"mistral": {
"args": ["TheBloke/Mistral-7B-Instruct-v0.1-GGUF"],
"kwargs": {"model_file": "mistral-7b-instruct-v0.1.Q4_K_M.gguf"},
},
}
async def callback(contents: str, user: str, instance: pn.chat.ChatInterface):
for model in MODEL_ARGUMENTS:
if model not in pn.state.cache:
pn.state.cache[model] = AutoModelForCausalLM.from_pretrained(
*MODEL_ARGUMENTS[model]["args"],
**MODEL_ARGUMENTS[model]["kwargs"],
gpu_layers=1,
)
llm = pn.state.cache[model]
response = llm(contents, max_new_tokens=512, stream=True)
message = None
for chunk in response:
message = instance.stream(chunk, user=model.title(), message=message)
chat_interface = pn.chat.ChatInterface(callback=callback)
chat_interface.send(
"Send a message to get a reply from both Llama 2 and Mistral (7B)!",
user="System",
respond=False,
)
chat_interface.servable()
运行 `panel serve app.py` 或 `panel serve app.ipynb` 后,您可以与 Llama2 和 Mistral 聊天并直接比较它们的回复。
我们能用 LangChain 构建相同的聊天机器人吗?是的!LangChain 是一个用于开发 LLM 应用程序的框架,许多人发现它很有用。
"""
Demonstrates how to use the ChatInterface widget to create a chatbot using
Llama2 and Mistral.
"""
import panel as pn
from langchain.chains import LLMChain
from langchain.llms import CTransformers
from langchain.prompts import PromptTemplate
pn.extension()
MODEL_KWARGS = {
"llama": {
"model": "TheBloke/Llama-2-7b-Chat-GGUF",
"model_file": "llama-2-7b-chat.Q5_K_M.gguf",
},
"mistral": {
"model": "TheBloke/Mistral-7B-Instruct-v0.1-GGUF",
"model_file": "mistral-7b-instruct-v0.1.Q4_K_M.gguf",
},
}
llm_chains = {}
TEMPLATE = """<s>[INST] You are a friendly chat bot who's willing to help answer the user:
{user_input} [/INST] </s>
"""
async def callback(contents: str, user: str, instance: pn.chat.ChatInterface):
config = {"max_new_tokens": 256, "temperature": 0.5}
for model in MODEL_KWARGS:
if model not in llm_chains:
instance.placeholder_text = (
f"Downloading {model}, this may take a few minutes,"
f"or longer, depending on your internet connection."
)
llm = CTransformers(**MODEL_KWARGS[model], config=config)
prompt = PromptTemplate(template=TEMPLATE, input_variables=["user_input"])
llm_chain = LLMChain(prompt=prompt, llm=llm)
llm_chains[model] = llm_chain
instance.send(
await llm_chains[model].apredict(user_input=contents),
user=model.title(),
respond=False,
)
chat_interface = pn.chat.ChatInterface(callback=callback, placeholder_threshold=0.1)
chat_interface.send(
"Send a message to get a reply from both Llama 2 and Mistral (7B)!",
user="System",
respond=False,
)
chat_interface.servable()
运行 `panel serve app.py` 或 `panel serve app.ipynb`,我们将获得一个使用 LangChain 与 Llama2 和 Mistral 交互的聊天机器人!
在本博文中,我们演示了如何运行 Mistral 7B 指令模型,如何使用流式完成和异步生成器来提高性能,如何使用 Panel 的聊天界面小部件构建聊天机器人,如何使用 Mistral 7B 和 Llama2 7B 构建聊天机器人,最后是如何使用 LangChain 构建此聊天机器人。希望您发现本博文有价值。快乐编码!
注意:
所有这些工具都是开源的,每个人都可以免费使用,但如果您想从 Anaconda 的 AI 和 Python 应用程序专家那里获得一些入门帮助,请联系 [email protected]!