การปรับแต่ง LLM
ในด้านโดเมนของโมเดล AI ปัจจุบัน มีหลากหลายของโมเดล และการผสานทางทางการเป็นทางการของ LangChain ไม่ครอบคลุมโมเดลทั้งหมด บางครั้งคุณอาจต้องการปรับแต่งโมเดลและผสานทางทางทางการของคุณเข้ากับกรอบงาน LangChain
บทนี้จะแนะนำวิธีการสร้างคลุม LLM ที่ปรับแต่ง ทำให้คุณสามารถใช้โมเดลของคุณเองหรือโมเดลที่ไม่ได้รับการสนับสนุนจาก LangChain ได้อย่างสะดวก
ใน LangChain หากคุณต้องการใช้ LLM ของคุณเองหรือคลุมที่แตกต่างจากคลุมที่ได้รับการสนับสนุนจาก LangChain คุณสามารถสร้างคลุม LLM ที่ปรับแต่ง คลุม LLM ที่ปรับแต่งเพียงแค่สร้างสองเม็ดอย่างที่จำเป็นต่อไปนี้
- เมทอด
_call
ที่มีอาร์กิวเมนต์เป็นสตริง บางครั้งสามารถใส่คำหยุดทางเลือกได้ และส่งค่ากลับเป็นสตริง โดยการดำเนินการของโมเดลจะอยู่ในเมทอด_call
- แอตทริบิวต์
_llm_type
ที่คืนค่าเป็นสตริงที่แทนชือโมเดล เฉพาะเพื่อการล็อก
นอกจากเมทอดที่จำเป็นแล้ว คลุม LLM ที่ปรับแต่งยังสามารถสร้างเมทอดทางเลือกได้ดังต่อไปนี้
- แอตทริบิวต์
_identifying_params
ที่ใช้ช่วยในการพิมพ์คลาส ควรคืนค่าเป็นดิกชันนารี
การปรับ LLM ที่ปรับแต่งอย่างง่าย
ให้เรามาสร้างคลุม LLM ที่ปรับแต่งที่ง่ายมากที่เพียงแค่คืนค่าตัวอักษรแรก n ตัวของข้อมูลที่เข้า
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 "custom"
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("stop kwargs are not permitted.")
return prompt[: self.n]
@property
def _identifying_params(self) -> Mapping[str, Any]:
"""Get the identifying parameters."""
return {"n": self.n}
ตอนนี้เราสามารถใช้คลุม LLM ที่ปรับแต่งนี้ได้เช่นเดียวกับคลุม LLM อื่น ๆ อีก
การใช้งานคลุม LLM ที่ปรับแต่ง
เราสามารถสร้างอ็อบเจ็กต์ของคลุม LLM และใช้งานมันได้ เพื่อสาธิตวิธีการเรียกใช้คลุม LLM ที่ปรับแต่งและปรับแต่งผลลัพธ์ที่พิมพ์
llm = CustomLLM(n=10)
llm.invoke("This is a foobar thing")
'This is a '
เรายังสามารถพิมพ์คลุม LLM และดูผลลัพธ์ที่ปรับแต่งของมัน
print(llm)
CustomLLM
Params: {'n': 10}
การปรับแต่งโมเดลแชท
ที่นี่เราจะอธิบายวิธีการปรับแต่งโมเดลแชทของ LangChain
ข้อมูลเข้าและข้อมูลออกของข้อความ
ในโมเดลแชท ข้อความคือศูนย์ในข้อมูลเข้าและข้อมูลออก ข้อความคือเนื้อหาที่ผู้ใช้ป้อนเข้าและการตอบสนองที่สร้างขึ้นโดยโมเดล
ข้อความ
โมเดลแชทรับข้อความเป็นข้อมูลเข้าและจากนั้นสร้างข้อความหรือมากกว่าหนึ่งข้อความเป็นข้อมูลออก ใน LangChain มีหลายประเภทข้อความที่มีอยู่แบบซึ่งรวมไปถึง
-
SystemMessage
: ใช้เริ่มต้นพฤติกรรม AI โดยทั่วไปจะเป็นข้อความแรกในชุดข้อความที่ป้อนเข้า -
HumanMessage
: แสดงสิ่งตอบสนองของผู้ใช้กับโมเดลแชท -
AIMessage
: แทนข้อความจากโมเดลแชท ซึ่งอาจเป็นข้อความหรือคำขอการเรียกใช้เครื่องมือ -
FunctionMessage
/ToolMessage
: ใช้ส่งผลลัพธ์ของการเรียกใช้เครื่องมือกลับไปยังโมเดล
การใช้ประเภทข้อความเหล่านี้สามารถขยายและปรับแต่งตามความต้องการเฉพาะ เช่นการปรับตัวตามพารามิเตอร์ function และ tool ของ OpenAI
from langchain_core.messages import (
AIMessage,
BaseMessage,
FunctionMessage,
HumanMessage,
SystemMessage,
)
Fluent Variants
ข้อความแชททั้งหมดมีตัวแปรทางชีวิตที่เรียกว่า Chunk
ในชื่อของพวกเขา
from langchain_core.messages import (
AIMessageChunk,
FunctionMessageChunk,
HumanMessageChunk,
SystemMessageChunk,
ToolMessageChunk,
)
Chunk
เหล่านี้ใช้เมื่อสตรีมมิ่งโมเดลแชทและแต่ละตัวกำหนดแอททริบิวต์สะสม
ตัวอย่าง
AIMessageChunk(content="Hello") + AIMessageChunk(content=" world!")
คืนค่า
AIMessageChunk(content='Hello world!')
โมเดลแชทง่าย
การสืบทอดจาก SimpleChatModel
ช่วยให้การปรับปรุงโมเดลแชทที่ง่ายได้อย่างรวดเร็ว
แม้ว่ามันอาจจะไม่รวมฟังก์ชันทั้งหมดที่จำเป็นสำหรับโมเดลแชท แต่มันทำให้เราสามารถทำการปรับเปลี่ยนไปสู่ BaseChatModel
ที่อธิบายไว้ด้านล่างได้
การสืบทอดจาก SimpleChatModel
ต้องการการปรับเพิ่มเติมจากต่อไปนี้:
- วิธี
_call
- การปรับใช้งานของการเรียกใช้ API ของโมเดลภายนอก
เพิ่มเติมได้จาก:
- แอตทริบิวต์
_identifying_params
- ใช้ในการบันทึกข้อมูลพารามิเตอร์ของโมเดล
ตัวเลือก:
- วิธี
_stream
- ใช้สำหรับการปรับใช้กระแสเอาท์พุต
โมเดลแชทเบส
การสืบทอดจาก BaseChatModel
ต้องการการปรับใช้ของวิธี _generate
และแอตทริบิวต์ _llm_type
ตัวเลือกคือการปรับใช้ของวิธี _stream
, _agenerate
, _astream
, และ _identifying_params
ก็เป็นไปได้
ตัวอย่างของโมเดลแชทที่กำหนดเอง
ในส่วนนี้เราจะสาธิตการปรับใช้โค้ดของโมเดลแชทที่กำหนดเองที่เรียก CustomChatModelAdvanced
ที่รวมการสร้างผลลัพธ์แชท การเอาท์พุตแบบสตรีม และการปรับใช้แบบสตรีมแบบไม่รวมกัน
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):
"""Implement a custom chat model that returns the first `n` characters of the last message."""
n: int
"""Custom model parameter"""
def _generate(
self,
messages: List[BaseMessage],
stop: Optional[List[str]] = None,
run_manager: Optional[CallbackManagerForLLMRun] = None,
**kwargs: Any,
) -> ChatResult:
"""ที่นี่ ตรรกะการเรียกโมเดลถูกปรับใช้ โดยภาคลอจิกการเรียก API ของโมเดลภายนอกโดยปกติ และจากนั้นห่อผลลัพธ์ที่คืนโดย API เข้ากับรูปแบบที่ langchain สามารถรับรู้ได้
คำอธิบายพารามิเตอร์ที่สำคัญ:
messages: ลิสต์ที่ประกอบด้วยข้อความโปรมท์
"""
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]:
"""การปรับใช้แบบสตรีมของโมเดล โดยมีคุณสมบัติคล้ายกับวิธี `_generate` แต่มีการปรับใช้แบบสตรีมของการเอาท์พุต"""
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]:
"""เวอร์ชันแบบไม่รวมกันของวิธีการปรับใช้ `stream`"""
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:
"""คืนค่าแท็กของโมเดลที่กำหนดเอง"""
return "echoing-chat-model-advanced"
@property
def _identifying_params(self) -> Dict[str, Any]:
"""คืนค่าข้อมูลดีบั๊กที่กำหนดเอง"""
return {"n": self.n}
การทดสอบโมเดลแชทที่กำหนดเอง
มาทดสอบโมเดลแชท ได้ด้วยการใช้วิธี invoke
, batch
, stream
และการปรับใช้แบบสตรีมแบบไม่รวมกัน
model = CustomChatModelAdvanced(n=3)
model.invoke([HumanMessage(content="hello!")])
model.invoke("hello")
model.batch(["hello", "goodbye"])
for chunk in model.stream("cat"):
print(chunk.content, end="|")
async for chunk in model.astream("cat"):
print(chunk.content, end="|")
async for event in model.astream_events("cat", version="v1"):
print(event)