Tùy chỉnh LLM
Trong lĩnh vực mô hình trí tuệ nhân tạo hiện tại, có rất nhiều mô hình khác nhau và tích hợp chính thức của LangChain không bao phủ tất cả các mô hình. Đôi khi bạn có thể cần tùy chỉnh một mô hình và tích hợp nó vào khung công việc của LangChain.
Chương này sẽ giới thiệu cách tạo một lớp bọc LLM tùy chỉnh, giúp bạn dễ dàng sử dụng mô hình riêng hoặc các mô hình không được hỗ trợ bởi LangChain.
Trong LangChain, nếu bạn muốn sử dụng LLM riêng hoặc một lớp bọc khác so với lớp bọc được hỗ trợ bởi LangChain, bạn có thể tạo một lớp bọc LLM tùy chỉnh. Một LLM tùy chỉnh chỉ cần thực hiện hai phương thức bắt buộc sau:
- Một phương thức
_call
, nhận một chuỗi làm đầu vào, một số từ dừng tùy chọn và trả về một chuỗi, thực hiện việc gọi mô hình trong phương thức_call
. - Một thuộc tính
_llm_type
, trả về một chuỗi biểu diễn tên mô hình, chỉ được sử dụng cho mục đích ghi nhật ký.
Ngoài các phương thức bắt buộc, một LLM tùy chỉnh cũng có thể thực hiện một phương thức tùy chọn:
- Một thuộc tính
_identifying_params
, được sử dụng để giúp in ra lớp. Nó nên trả về một từ điển.
Thực hiện một LLM tùy chỉnh đơn giản
Hãy thực hiện một LLM tùy chỉnh rất đơn giản chỉ trả về n ký tự đầu tiên của đầu vào.
from typing import Any, List, Mapping, Optional
from langchain_core.callbacks.manager import CallbackManagerForLLMRun
from langchain_core.language_models.llms import LLM
class CustomLLM(LLM):
n: int
@property
def _llm_type(self) -> str:
return "tùy chỉnh"
def _call(
self,
prompt: str,
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> str:
if stop is not None:
raise ValueError("Tham số dừng không được phép.")
return prompt[: self.n]
@property
def _identifying_params(self) -> Mapping[str, Any]:
"""Lấy các tham số xác định."""
return {"n": self.n}
Bây giờ chúng ta có thể sử dụng LLM tùy chỉnh này giống như bất kỳ LLM nào khác.
Sử dụng LLM tùy chỉnh
Chúng ta có thể khởi tạo và sử dụng đối tượng LLM tùy chỉnh, làm thể nào để gọi LLM tùy chỉnh và tùy chỉnh kết quả in ra.
llm = CustomLLM(n=10)
llm.invoke("Đây là một cái gì đó")
'Đây là một '
Chúng ta cũng có thể in ra LLM và xem kết quả in ra được tùy chỉnh.
print(llm)
CustomLLM
Tham số: {'n': 10}
Tùy chỉnh Mô hình Trò chuyện
Ở đây chúng ta sẽ giải thích cách tùy chỉnh mô hình trò chuyện của LangChain.
Đầu vào và Đầu ra Tin nhắn
Trong mô hình trò chuyện, tin nhắn là trọng tâm của đầu vào và đầu ra. Một tin nhắn là nội dung được nhập bởi người dùng và phản hồi được tạo ra bởi mô hình.
Tin nhắn
Mô hình trò chuyện nhận tin nhắn làm đầu vào và sau đó tạo ra một hoặc nhiều tin nhắn làm đầu ra. Trong LangChain, có một số loại tin nhắn tích hợp sẵn, bao gồm:
-
SystemMessage
: Được sử dụng để khởi tạo hành vi trí tuệ nhân tạo, thường được sử dụng như tin nhắn đầu tiên trong chuỗi các tin nhắn đầu vào. -
HumanMessage
: Đại diện cho sự tương tác của người dùng với mô hình trò chuyện. -
AIMessage
: Đại diện cho các tin nhắn từ mô hình trò chuyện, có thể là văn bản hoặc yêu cầu triệu hồi công cụ. -
FunctionMessage
/ToolMessage
: Được sử dụng để truyền kết quả của việc triệu hồi công cụ trở lại mô hình.
Việc sử dụng các loại tin nhắn này có thể được mở rộng và tùy chỉnh theo yêu cầu cụ thể, chẳng hạn như điều chỉnh dựa trên các tham số hành động
và công cụ
của OpenAI.
from langchain_core.messages import (
AIMessage,
BaseMessage,
FunctionMessage,
HumanMessage,
SystemMessage,
)
Biến thể trôi chảy
Tất cả các tin nhắn trò chuyện đều có một biến thể trôi chảy với Chunk
trong tên của chúng.
from langchain_core.messages import (
AIMessageChunk,
FunctionMessageChunk,
HumanMessageChunk,
SystemMessageChunk,
ToolMessageChunk,
)
Các Chunk
này được sử dụng khi truyền dữ liệu mô hình trò chuyện và mỗi trong số chúng định nghĩa một thuộc tính tích lũy!
Ví dụ
AIMessageChunk(content="Xin chào") + AIMessageChunk(content=" thế giới!")
Trả về
AIMessageChunk(content='Xin chào thế giới!')
Mô hình Chat Đơn Giản
Kế thừa từ SimpleChatModel
cho phép triển khai một cách nhanh chóng một mô hình chat đơn giản.
Mặc dù có thể không tích hợp tất cả các chức năng cần thiết cho một mô hình chat, nó cung cấp một triển khai nhanh chóng. Nếu cần thêm tính năng, chuyển sang sử dụng BaseChatModel
được mô tả bên dưới là có thể.
Kế thừa từ SimpleChatModel
yêu cầu triển khai các giao diện sau:
- Phương thức
_call
- triển khai cuộc gọi API mô hình bên ngoài.
Ngoài ra, có thể được xác định:
- Thuộc tính
_identifying_params
- được sử dụng để ghi lại thông tin tham số hóa của mô hình.
Tùy chọn:
- Phương thức
_stream
- được sử dụng để triển khai đầu ra lưu trữ.
Mô Hình Chat Cơ Bản
Kế thừa từ BaseChatModel
yêu cầu triển khai phương pháp _generate
và thuộc tính _llm_type
. Tùy chọn, triển khai của _stream
, _agenerate
, _astream
và _identifying_params
là có thể.
Ví dụ về Mô Hình Chat Tùy chỉnh
Trong phần này, chúng ta sẽ thể hiện việc triển khai mã của một mô hình chat tùy chỉnh được gọi là CustomChatModelAdvanced
, bao gồm việc tạo kết quả chat, đầu ra lưu trữ và triển khai đầu ra lưu trữ không đồng bộ.
from typing import Any, AsyncIterator, Dict, Iterator, List, Optional
from langchain_core.callbacks import (
AsyncCallbackManagerForLLMRun,
CallbackManagerForLLMRun,
)
from langchain_core.language_models import BaseChatModel, SimpleChatModel
from langchain_core.messages import AIMessageChunk, BaseMessage, HumanMessage
from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult
from langchain_core.runnables import run_in_executor
class CustomChatModelAdvanced(BaseChatModel):
"""Triển khai một mô hình chat tùy chỉnh trả về `n` ký tự đầu tiên của tin nhắn cuối cùng."""
n: int
"""Tham số mô hình tùy chỉnh"""
def _generate(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> ChatResult:
"""Ở đây, logic gọi mô hình được triển khai, thường bằng cách gọi API của một mô hình bên thứ ba, sau đó đóng gói kết quả trả về từ API vào một định dạng mà langchain có thể nhận dạng.
Giải thích tham số chính:
messages: Một danh sách các đầu vào bao gồm các tin nhắn
"""
last_message = messages[-1]
tokens = last_message.content[: self.n]
message = AIMessage(content=tokens)
generation = ChatGeneration(message=message)
return ChatResult(generations=[generation])
def _stream(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> Iterator[ChatGenerationChunk]:
"""Triển khai đầu ra lưu trữ mô hình, tương tự như phương thức _generate, nhưng với xử lý đầu ra lưu trữ."""
last_message = messages[-1]
tokens = last_message.content[: self.n]
for token in tokens:
chunk = ChatGenerationChunk(message=AIMessageChunk(content=token))
if run_manager:
run_manager.on_llm_new_token(token, chunk=chunk)
yield chunk
async def _astream(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[AsyncCallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> AsyncIterator[ChatGenerationChunk]:
"""Phiên bản không đồng bộ của phương thức `stream` được triển khai"""
result = await run_in_executor(
None,
self._stream,
messages,
stop=stop,
run_manager=run_manager.get_sync() if run_manager else None,
**kwargs,
)
for chunk in result:
yield chunk
@property
def _llm_type(self) -> str:
"""Trả về nhãn của mô hình tùy chỉnh"""
return "mô-hình-chat-nâng-cao"
@property
def _identifying_params(self) -> Dict[str, Any]:
"""Trả về thông tin gỡ lỗi tùy chỉnh"""
return {"n": self.n}
Kiểm thử Mô Hình Chat Tùy chỉnh
Hãy kiểm thử mô hình chat, bao gồm sử dụng các phương thức invoke
, batch
, stream
, và triển khai đầu ra lưu trữ không đồng bộ.
model = CustomChatModelAdvanced(n=3)
model.invoke([HumanMessage(content="Xin chào!")])
model.invoke("Xin chào")
model.batch(["Xin chào", "Tạm biệt"])
for chunk in model.stream("mèo"):
print(chunk.content, end="|")
async for chunk in model.astream("mèo"):
print(chunk.content, end="|")
async for event in model.astream_events("mèo", version="v1"):
print(event)