채팅 기초
채팅 기초 (Chat basics)
채팅 모델은 메시지를 보내면 응답을 받는 대화형 모델이에요. 명령줄에서 모델과 대화하고, Transformers로 채팅을 구성·포맷하는 방법을 살펴볼게요.
출처: 문서
본문
채팅 모델은 메시지를 보내면 응답을 받는 대화형 모델이에요. 2023년 중반 이후의 대부분의 언어 모델은 채팅 모델이며 "instruct" 또는 "instruction-tuned" 모델이라고 불리기도 해요. 채팅을 지원하지 않는 모델은 흔히 "base" 또는 "pretrained" 모델이라고 해요.
크고 최신 모델이 일반적으로 더 유능하지만, 특정 도메인(의료, 법률 텍스트, 비영어권 언어 등)에 특화된 모델이 더 큰 모델을 능가하는 경우가 많아요. OpenLLM과 LMSys Chatbot Arena 같은 리더보드를 시도해 사용 사례에 가장 좋은 모델을 찾는 데 도움을 받을 수 있어요.
이 가이드는 명령줄에서 Transformers로 채팅 모델을 빠르게 불러오는 법, 대화를 구성·포맷하는 법, TextGenerationPipeline으로 채팅하는 법을 보여줘요.
chat CLI
Transformers를 설치한 뒤 명령줄에서 모델과 직접 채팅할 수 있어요. 아래 명령은 모델과의 대화형 세션을 시작하는데, 세션 시작 시 기본 명령 몇 개가 표시돼요.
아래 명령들을 실행하려면
transformers serve가 실행 중인지 확인하세요.
transformers chat Qwen/Qwen2.5-0.5B-Instruct
아무 generate 플래그나 arg_1=value_1 arg_2=value_2 ... 형식으로 함께 넘길 수 있어요.
transformers chat Qwen/Qwen2.5-0.5B-Instruct do_sample=False max_new_tokens=10
전체 옵션 목록은 아래 명령을 실행하세요.
transformers chat -h
채팅은 AutoClass 위에 구현되고, 텍스트 생성과 채팅의 도구를 사용해요. 내부적으로는 transformers serve CLI를 사용해요 (문서).
TextGenerationPipeline
TextGenerationPipeline은 "chat mode"가 있는 고수준 텍스트 생성 클래스예요. 대화형 모델이 감지되고 채팅 프롬프트가 올바르게 포맷되면 채팅 모드가 활성화돼요.
채팅 모델은 메시지 리스트(채팅 이력)를 입력으로 받아요. 각 메시지는 role과 content 키를 가진 딕셔너리예요.
채팅을 시작하려면 user 메시지 하나를 추가해요. 선택적으로 system 메시지를 포함해 모델에 어떻게 행동할지 지시할 수도 있어요.
chat = [
{"role": "system", "content": "You are a helpful science assistant."},
{"role": "user", "content": "Hey, can you explain gravity to me?"}
]
TextGenerationPipeline을 만들고 chat을 넘겨요. 큰 모델에서는 device_map="auto"를 설정하면 모델을 더 빨리 불러오고 사용 가능한 가장 빠른 기기에 자동으로 배치해요.
import torch
from transformers import pipeline
pipeline = pipeline(task="text-generation", model="HuggingFaceTB/SmolLM2-1.7B-Instruct", dtype="auto", device_map="auto")
response = pipeline(chat, max_new_tokens=512)
print(response[0]["generated_text"][-1]["content"])
성공하면 모델의 응답을 볼 수 있어요! 대화를 계속하려면 채팅 이력을 모델의 응답으로 업데이트해야 해요. chat에 텍스트를 추가(assistant 역할 사용)하거나, 가장 최근 응답을 포함한 전체 채팅 이력을 담은 response[0]["generated_text"]를 읽어서 할 수 있어요.
모델의 응답을 얻은 뒤에는 채팅 이력에 새 user 메시지를 추가해 대화를 계속할 수 있어요.
chat = response[0]["generated_text"]
chat.append(
{"role": "user", "content": "Woah! But can it be reconciled with quantum mechanics?"}
)
response = pipeline(chat, max_new_tokens=512)
print(response[0]["generated_text"][-1]["content"])
이 과정을 반복하면 모델의 컨텍스트 윈도우가 소진되거나 메모리가 부족할 때까지 원하는 만큼 대화를 계속할 수 있어요.
성능과 메모리 사용 (Performance and memory usage)
Transformers는 기본적으로 모델을 전체 float32 정밀도로 불러오는데, 8B 모델의 경우 약 32GB의 메모리가 필요해요! torch_dtype="auto" 인자를 사용하면 보통 그런 모델로 학습된 bfloat16을 사용해 메모리 사용을 줄일 수 있어요.
[!TIP] 사용 가능한 다양한 양자화 백엔드에 대한 자세한 내용은 Quantization 문서를 참고하세요.
메모리를 더 낮추려면 bitsandbytes로 모델을 8-bit나 4-bit로 양자화할 수 있어요. 원하는 양자화 설정으로 BitsAndBytesConfig를 만들고 파이프라인의 model_kwargs 파라미터에 넘겨요. 아래 예시는 모델을 8-bit로 양자화해요.
from transformers import pipeline, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_8bit=True)
pipeline = pipeline(task="text-generation", model="meta-llama/Meta-Llama-3-8B-Instruct", device_map="auto", model_kwargs={"quantization_config": quantization_config})
일반적으로 모델 크기와 성능은 직접적으로 상관관계가 있어요. 큰 모델은 생성된 토큰마다 각 활성 파라미터를 메모리에서 읽어야 하므로 메모리를 더 요구할 뿐 아니라 더 느려요. 이것이 LLM 텍스트 생성의 병목이고, 생성 속도를 높이는 주요 옵션은 모델을 양자화하거나 메모리 대역폭이 더 높은 하드웨어를 쓰는 것이에요. 컴퓨팅 파워를 더 추가하는 건 의미 있게 도움이 되지 않아요.
또한 추측 디코딩(speculative decoding) 같은 기법을 시도할 수 있어요. 더 작은 모델이 후보 토큰을 생성하고 큰 모델이 이를 검증하는 방식이에요. 후보 토큰이 맞으면 큰 모델이 한 번에 두 개 이상의 토큰을 생성할 수 있어요. 이는 대역폭 병목을 크게 완화하고 생성 속도를 높여요.
[!TIP] Mixtral, Qwen2MoE, GPT-OSS 같은 Mixture-of-Expert (MoE) 모델은 파라미터가 많지만 각 토큰을 생성할 때 작은 일부만 "활성화"해요. 결과적으로 MoE 모델은 메모리 대역폭 요구가 훨씬 낮고 같은 크기의 일반 LLM보다 빠를 수 있어요. 다만 추측 디코딩 같은 기법은 새로 추측되는 토큰마다 더 많은 파라미터가 활성화되므로 MoE 모델에서는 효과가 없어요.
더 알아보기 (Learn more)
- 연속 배칭 문서에서 서빙을 살펴보세요.
- 토크나이저 커스터마이징 문서