올바른 Generator 고르기
올바른 Generator 고르기
Haystack에서 생성형 언어 모델(Generative LLM)과 상호작용할 때 올바른 ChatGenerator를 고르는 방법을 설명하는 페이지예요. 여러 제공 업체의 독점·오픈 모델 사용법과 온프레미스에서 오픈 모델을 쓰는 옵션을 다룹니다.
출처: 문서
본문
Haystack에서 ChatGenerator는 생성형 언어 모델과 상호작용하는 주된 인터페이스예요. 평문 프롬프트 문자열이나 ChatMessage 리스트를 받아 "replies"로 ChatMessage를 반환하며, Function Calling과 Multimodal 입력을 지원합니다.
이 가이드는 선호도와 컴퓨팅 자원에 맞는 ChatGenerator를 고르는 과정을 단순화하는 데 초점을 맞춰요. 특정 모델 자체를 고르는 것이 아니라 모델 유형과 Haystack ChatGenerator를 고르는 것에 집중합니다. 여러 경우에 같은 모델을 쓰는 방법이 다양하거든요.
스트리밍 지원 (Streaming Support)
스트리밍은 LLM 응답을 한 번에 모두 생성한 뒤 출력하는 대신, 단어 단위로 조금씩 출력하는 것을 말해요.
어떤 Generator가 스트리밍을 지원하는지는 Generators 개요 페이지에서 확인할 수 있습니다.
스트리밍을 켜면 generator는 매 StreamingChunk마다 streaming_callback을 호출합니다. 각 청크는 정확히 다음 중 하나를 나타내요:
- Tool calls — 모델이 도구/함수 호출을 만드는 중.
chunk.tool_calls를 읽어요. - Tool result — 도구가 끝나 출력을 반환함.
chunk.tool_call_result를 읽어요. - Text tokens — 일반적인 어시스턴트 텍스트.
chunk.content를 읽어요. - Reasoning tokens — 확장 사고(extended thinking) 출력(지원하는 모델의 경우).
chunk.reasoning을 읽어요.
청크마다 이 필드 중 하나만 나타납니다. 경계(boundary)를 감지하려면 chunk.start와 chunk.finish_reason을 쓰고, 추적에는 chunk.index와 chunk.component_info를 사용하세요.
여러 후보(candidates)를 지원하는 제공 업체의 경우 스트리밍하려면 n=1로 설정하세요.
파라미터 상세 내용은 StreamingChunk에 대한 API Reference를 참고하세요.
가장 간단한 방법은 내장된 print_streaming_chunk 함수를 쓰는 것이에요. 모든 청크 유형을 처리하고 stdout에 형식화된 출력을 프린트합니다:
from haystack.components.generators.utils import print_streaming_chunk
generator = SomeChatGenerator(streaming_callback=print_streaming_chunk)
# ChatGenerators accept either a list[ChatMessage] or a plain prompt string.
동기 및 비동기 콜백
스트리밍 가능 컴포넌트(OpenAIChatGenerator, HuggingFaceAPIChatGenerator, TransformersChatGenerator, Agent 등)는 비동기 컨텍스트(run_async 또는 async 파이프라인 실행)에서 동기·비동기 스트리밍 콜백을 모두 받아들여요. run_async에 동기 콜백을 전달하면 콜백이 이벤트 루프 위에서 동기적으로 실행되며 이를 막을 수 있어 경고가 기록되지만, 실행은 진행되고 예상대로 스트리밍됩니다. 비동기 컨텍스트에서 성능을 위해서는 비동기 콜백이 여전히 선호돼요.
import asyncio
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage, StreamingChunk
def print_chunk(chunk: StreamingChunk) -> None:
print(chunk.content, end="", flush=True)
async def main():
llm = OpenAIChatGenerator()
# a sync callback in an async context logs a warning and streams as expected
await llm.run_async(
[ChatMessage.from_user("Tell me about Italy")],
streaming_callback=print_chunk,
)
asyncio.run(main())
반대는 지원되지 않아요. 동기 run 메서드에 비동기 콜백을 전달하면, 코루틴을 동기 코드에서 await할 수 없으므로 오류가 발생합니다.
커스텀 콜백
커스텀 렌더링이 필요하면 직접 콜백을 작성하세요. 네 가지 청크 유형을 순서대로 처리합니다:
from haystack.dataclasses import StreamingChunk
def my_streaming_callback(chunk: StreamingChunk) -> None:
if chunk.start and chunk.index and chunk.index > 0:
print("\n\n", flush=True, end="")
# Tool Call streaming
if chunk.tool_calls:
for tool_call in chunk.tool_calls:
if chunk.start:
if chunk.index and tool_call.index > chunk.index:
print("\n\n", flush=True, end="")
print(
f">>> Tool Call: {tool_call.tool_name}\n>>> Arguments: ",
flush=True,
end="",
)
if tool_call.arguments:
print(tool_call.arguments, flush=True, end="")
# Tool Result streaming
if chunk.tool_call_result:
print(f">>> Tool Result\n{chunk.tool_call_result.result}", flush=True, end="")
# Text streaming
if chunk.content:
if chunk.start:
print(">>> Assistant\n", flush=True, end="")
print(chunk.content, flush=True, end="")
# Reasoning streaming
if chunk.reasoning:
if chunk.start:
print(">>> Reasoning\n", flush=True, end="")
print(chunk.reasoning.reasoning_text, flush=True, end="")
if chunk.finish_reason is not None:
print("\n\n", flush=True, end="")
에이전트와 도구
Agent는 streaming_callback을 전달하고(tool_streaming_callback_passthrough=True를 설정하면 도구를 받아들이는 도구에도 전달), finish_reason을 가진 최종 도구 결과 청크도 내보내서, 어시스턴트 텍스트가 재개되기 전에 UI가 "도구 단계"를 깨끗하게 닫을 수 있게 합니다. 기본 print_streaming_chunk가 이를 형식화해줍니다.
독점 모델 vs 오픈 가중치 모델
Generator를 고르기 전에 어떤 유형의 모델을 쓰고 싶은지 아는 게 도움이 돼요.
독점 모델 (Proprietary Models)
독점 모델을 쓰는 것은 생성형 언어 모델을 시작하는 빠른 방법이에요. 일반적인 방식은 API Key를 이용해 호스팅된 모델을 호출하는 것입니다. 보낸 토큰과 생성된 토큰 수를 기준으로 비용을 지불해요. 컴퓨팅은 제공 업체 인프라에서 실행되므로 로컬 머신에 큰 자원이 필요하지 않습니다. 이 모델들을 쓰면 데이터가 내 머신을 떠나 모델 제공 업체로 전송됩니다.
오픈 가중치 모델 (Open-weights Models)
오픈(가중치) 모델이란, 누구나 자신의 인프라에 배포할 수 있는 공개 가중치를 가진 모델을 말해요. 학습에 쓰인 데이터셋은 덜 공유되는 편입니다. 오픈 모델을 쓰는 이유는 모델에 대한 더 큰 투명성과 통제권을 포함해 다양해요.
상업적 사용: 모든 오픈 모델이 상업적 사용에 적합한 것은 아닙니다. 채택을 고려하기 전에 보통 Hugging Face에서 구할 수 있는 라이선스를 꼼꼼히 검토하시기 바랍니다.
모델이 오픈이라도, 주로 모델을 호스팅하고 인프라 측면을 처리해줄 제공 업체에 의존하고 싶어 모델 제공 업체를 쓸 수도 있어요. 이런 시나리오에서는 데이터가 내 머신에서 모델을 제공하는 제공 업체로 이동합니다.
모델이 실행되는 위치
모델이 어디서 실행되느냐는 독점-오픈 선택과는 별개의 결정이에요. 독점 모델은 항상 제공 업체 호스팅이지만, 오픈 가중치 모델은 아래 설명된 방식 중 어느 것으로든 서빙할 수 있습니다.
고르는 Generator는 주로 모델이 실행되는 위치와 호출하는 API에 따라 결정됩니다. 비용은 선택에 따라 달라질 수 있으며, 소비된 토큰(보내고 생성된 것)이나 모델 호스팅(보통 시간당 과금) 기준으로 지불해요.
제공 업체 호스팅 API (Provider-hosted APIs)
제공 업체 호스팅 API에서는 다른 사용자와 공유하는 모델 인스턴스를 활용하며, 지불은 보통 소비된 토큰(보내고 생성된 것) 기준입니다.
단일 공급 업체 API (Single-vendor APIs)
이 제공 업체들은 전용 API 뒤에서 자체 모델을 호스팅합니다. Haystack은 OpenAI, Azure, Google, Cohere, Mistral 등 여러 제공 업체의 모델을 지원하며 계속 추가되고 있어요.
멀티 모델 게이트웨이 (Multi-model Gateways)
여러 제공 업체가 단일 API로 많은 모델을 노출해서, 하나의 Generator로 서로 다른 벤더의 모델을 전환할 수 있습니다. 일부 제공 업체는 오픈 가중치 모델에 집중하고, 다른 업체는 독점 모델도 포함합니다:
- Amazon Bedrock — Amazon Titan 계열, AI21 Labs, Anthropic, Cohere의 독점 모델과 Meta의 Llama 같은 여러 오픈 모델에 접근을 제공해요.
- Hugging Face Inference Providers —
HuggingFaceAPIChatGenerator를 통해 사용할 수 있으며, 통합 인터페이스로 여러 제공 업체의 수백 개 LLM에 접근하게 해줍니다. - AIMLAPI, Comet API, NVIDIA, OpenRouter, STACKIT, Together AI, WatsonX — 각각 전용 Haystack 통합이 있어요.
- DeepInfra, Fireworks, FuturMix 및 기타 클라우드 제공 업체는 OpenAI 호환 인터페이스를 제공하며 OpenAI Generator로 사용할 수 있어요.
DeepInfra와 OpenAIChatGenerator를 쓰는 예시입니다:
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret
generator = OpenAIChatGenerator(
api_key=Secret.from_env_var("ENVVAR_WITH_API_KEY"),
api_base_url="https://api.deepinfra.com/v1",
model="Qwen/Qwen3.6-35B-A3B",
)
generator.run(messages=[ChatMessage.from_user("What is the best French cheese?")])
전용 클라우드 인스턴스 (Dedicated Cloud Instances)
이 경우 제공 업체가 모델의 전용(private) 인스턴스를 배포하며, 보통 시간당 과금합니다.
Haystack에서 이를 지원하는 컴포넌트:
- Amazon
SagemakerGenerator HuggingFaceAPIChatGenerator— HuggingFace Inference endpoints를 쿼리할 때
제공 업체 호스팅 API vs 전용 클라우드 인스턴스
제공 업체 호스팅 API를 고르는 이유:
- 비용 절감: 사용 패턴이 다양하거나 예산이 제한된 사용자에게 특히 적합한 비용 효율적 해결책에 접근할 수 있어요.
- 사용 용이성: 제공 업체가 인프라와 업데이트를 관리하므로 설정과 유지보수가 간단해져 사용자 친화적이에요.
전용 클라우드 인스턴스를 고르는 이유:
- 전용 자원: 인스턴스에 전용 자원을 보장해 일관된 성능을 확보하고 다른 사용자의 영향을 피할 수 있어요.
- 확장성: 요구에 따라 자원을 확장하며, 피크 시간엔 최적 성능을, 비수기엔 비용 절감을 보장해요.
- 예측 가능한 비용: 시간당 과금은 사용 패턴을 명확히 알 때 특히 더 예측 가능한 비용을 만들어줘요.
셀프 호스팅 / 온프레미스
온프레미스 모델은 오픈 모델을 내 머신이나 인프라에 호스팅하는 것이에요. 로컬 실험에 이상적이며, 충분한 컴퓨팅 자원이 있다면 데이터 프라이버시 때문에 외부 제공 업체로 데이터를 보내지 못하는 프로덕션 시나리오에도 적합합니다.
로컬 실험
- GPU:
TransformersChatGenerator는 Hugging Face Transformers 라이브러리 기반이에요. GPU 자원(예: Colab)이 있을 때 실험하기 좋습니다. GPU 자원이 부족하면 bitsandbytes, GPTQ, AWQ 같은 대안적 양자화 옵션을 지원합니다. 프로덕션에서 더 성능 좋은 해결책은 아래 옵션을 참고하세요. - CPU(+ GPU 가능 시):
LlamaCppChatGenerator는 Llama.cpp 라이브러리(LLM의 효율적 추론을 위한 C/C++ 프로젝트)를 사용해요. 특히 표준 머신(GPU 없어도)에서 이 모델들을 실행하기 적합한 양자화 GGUF 형식을 사용합니다. GPU 자원이 있으면 일부 레이어를 GPU로 오프로드해 속도를 높일 수 있어요. - CPU(+ GPU 가능 시):
OllamaChatGenerator는 Ollama 프로젝트 기반으로, LLM을 위한 Docker 같은 역할을 해요. 모델을 패키징·배포하는 간단한 방법을 제공합니다. 내부적으로 Llama.cpp 라이브러리 기반이라 여러 플랫폼에서 더 간결하게 실행할 수 있어요.
프로덕션에서 LLM 서빙
프로덕션에서 언어 모델을 실행하고 GPU 자원을 갖추고 싶다면 다음 해결책이 적합합니다. 빠른 추론과 다수의 동시 요청을 효율적으로 처리하는 혁신적 기법을 사용해요.
- vLLM — LLM용 고처리량·메모리 효율 추론/서빙 엔진이에요. Haystack은
vLLMChatGenerator로 vLLM을 지원합니다. - SGLang — 유사한 고성능 LLM 서빙 프레임워크예요. Haystack은 OpenAI Generator를 통해 지원합니다.
HuggingFaceAPIChatGenerator— 온프레미스에 배포된 TGI 인스턴스를 쿼리할 때. Hugging Face Text Generation Inference는 LLM을 효율적으로 배포·서빙하는 툴킷인데, 현재 유지보수 모드에 있습니다.
더 알아보기 (Learn more)
- Choosing the Right Generator — Haystack 공식 문서