제약 샘플링을 통한 LLM의 구조화된 출력 생성
대규모 언어 모델(LLM)은 비정형 데이터와 상호작용하는 방식을 변화시켜, 창의적인 텍스트를 생성하고, 인사이트를 추출하며, 작업을 자동화하는 시스템을 가능하게 했습니다. 그러나 이러한 모델은 자유 형식의 콘텐츠를 생성하지만, 출력이 JSON, XML 또는 사전 정의된 스키마와 같은 특정 형식을 따라야 할 때는 종종 한계를 보입니다. 이러한 한계는 코딩 어시스턴트, 의사결정 에이전트, 구조화된 정보 추출 시스템처럼 정밀성이 중요한 실제 사용 사례에서 매우 중요합니다.
최근 South Bay에서 열린 Unstructured Data Meetup에서 Zilliz의 Stefan Webb은 이 과제에 대한 실용적인 해결책인 제약 샘플링을 발표했습니다. 이 글에서는 비정형 데이터 처리에서 시맨틱 검색의 역할, 유한 상태 머신이 신뢰할 수 있는 생성을 가능하게 하는 방식, 최신 도구를 사용한 실용적인 구현을 포함하여 그의 발표에서 얻은 핵심 인사이트를 살펴보겠습니다. 또한 이러한 기법이 벡터 데이터베이스와 어떻게 통합되어 비정형 데이터 처리와 구조화된 출력 생성을 모두 다루는 견고한 AI 애플리케이션을 만드는지도 살펴보겠습니다.
시맨틱 검색이란 무엇이며 왜 중요한가
시맨틱 검색은 쿼리 이면의 의미와 맥락에 초점을 맞춘다는 점에서 전통적인 키워드 기반 검색과 다릅니다. 정확히 일치하는 단어를 찾는 대신, 시맨틱 검색은 용어 간의 관계를 처리하여 더 관련성 높은 결과를 제공합니다. 이 기능은 텍스트, 이미지, 오디오, 비디오를 포함해 대부분의 데이터가 비정형인 세상에서 필수적입니다. 다음은 비정형 데이터가 실행 가능한 인사이트로 전환되는 방식입니다.
그림: 비정형 데이터를 실행 가능한 인사이트로 전환하는 파이프라인
이 파이프라인은 문서, 이미지, 오디오 녹음, 비디오를 포함한 원시 데이터를 수집하는 것으로 시작합니다. 데이터는 딥러닝 모델을 통과하여 데이터의 의미적 속성을 고차원 수치 표현으로 나타내는 벡터 임베딩을 생성합니다. 이러한 임베딩은 효율적인 검색을 위해 Milvus 와 같은 벡터 데이터베이스 에 저장됩니다. 마지막으로, 시맨틱 검색 알고리즘은 이러한 임베딩을 대상으로 작동하여 관련성을 기준으로 결과를 식별하고 순위를 매깁니다. 이제 벡터 공간이 어떻게 보이는지 살펴보겠습니다.
그림: 유사한 개념을 함께 클러스터링하는 임베딩 공간의 시각화
임베딩 공간의 시각화에서는 유사한 개념이 함께 클러스터링됩니다. 예를 들어 꼬리를 흔드는 행복한 개와 미소 짓는 개 같은 구문은 유사한 의미를 전달하기 때문에 서로 가깝게 그룹화됩니다. 반면 큰 건물처럼 관련 없는 주제는 공간에서 멀리 떨어져 배치됩니다. 이러한 클러스터링을 통해 시스템은 쿼리가 다른 표현을 사용하더라도 의미적으로 관련된 결과를 검색할 수 있습니다.
비정형 데이터의 양이 증가함에 따라 시맨틱 검색은 점점 더 중요해지고 있습니다. 2025년까지 생성되는 데이터의 90% 이상이 비정형일 것으로 추정되며, 이는 의미적 이해가 가능한 시스템의 필요성을 강조합니다.
그림: 2025년에 새롭게 생성되는 데이터의 90% 이상은 비정형 데이터가 될 것입니다.
다항 샘플링: 텍스트 생성의 기반
LLM의 텍스트 생성은 학습 데이터에서 학습한 확률을 기반으로 토큰 단위로 시퀀스를 생성하는 과정인 다항 샘플링에 의해 구동됩니다. 각 토큰은 단어, 문자 또는 단어의 일부를 나타낼 수 있으며, 모델은 확률 분포에서 샘플링하여 다음 토큰을 선택합니다.
그림: LLM의 기본 다항 샘플링
알고리즘은 빈 시퀀스로 시작하여 시퀀스가 완성되거나 중지 조건이 충족될 때까지 토큰을 반복적으로 추가합니다. 각 단계에서 모델은 가능한 모든 다음 토큰에 대한 확률을 계산하고 이러한 확률을 기반으로 하나를 샘플링합니다. 이 방법은 자유 형식 텍스트를 생성하는 데 뛰어나지만, 구조적 규칙을 강제하는 메커니즘은 부족합니다. 예를 들어, 유효한 JSON이나 잘 구성된 코드를 생성하려면 구조적 오류를 수정하기 위한 후처리가 필요한 경우가 많습니다.
이러한 한계는 출력이 미리 정의된 구조를 따르도록 보장하기 위해 생성 프로세스에 제약 조건을 통합하는 가이드 샘플링의 필요성을 강조합니다.
가이드 샘플링: 생성 중 구조적 규칙 강제
가이드 샘플링은 생성을 안내하는 제약 조건을 적용하여 기본 다항 샘플링 프로세스를 향상합니다. 이러한 제약 조건은 각 단계에서 유효하지 않은 토큰을 걸러내는 이진 마스크를 통해 강제됩니다. 마스크는 출력의 현재 컨텍스트를 기반으로 동적으로 조정되어 생성된 시퀀스가 유효하게 유지되도록 보장합니다.
그림: 가이드 샘플링을 통한 구조화된 출력
예를 들어, JSON을 생성할 때 시스템은 여는 중괄호 { 뒤의 다음 토큰을 필드 이름으로 제한할 수 있습니다. 마찬가지로, 코드 생성에서는 제약 조건이 유효하지 않은 문자나 불완전한 문장을 차단하여 올바른 구문을 강제할 수 있습니다. 이 접근 방식은 생성 후 광범위한 검증이나 수정의 필요성을 없애며, 정보 추출 및 의사 결정 에이전트와 같은 애플리케이션에 특히 유용합니다.
가이드 샘플링은 구조를 생성 프로세스에 직접 도입함으로써 LLM의 창의적 능력과 구조화된 출력에 필요한 정밀성 사이의 간극을 메웁니다. 이 방법은 텍스트 생성에서 유한 상태 머신(FSM)을 구현하기 위한 기반입니다.
유한 상태 머신: 구조적 일관성 강제
유한 상태 머신(FSM)은 제약 조건을 강제하기 위한 공식적인 프레임워크를 제공함으로써 가이드 샘플링의 개념을 한 단계 더 발전시킵니다. FSM은 유한한 수의 상태와 그 사이의 전이를 갖는 계산 모델입니다. 각 상태는 출력 생성 프로세스의 한 지점을 나타내며, 전이는 현재 컨텍스트를 기반으로 유효한 경로를 정의합니다. FSM을 생성 파이프라인에 통합하면 엄격한 구조적 규칙을 동적으로 강제할 수 있습니다.
FSM에서는 상태가 미리 정의되어 있으며, 각 상태는 생성 프로세스의 특정 조건이나 단계를 나타냅니다. 상태 간 전이는 생성되는 입력이나 토큰을 기반으로 발생합니다. 허용 가능한 전이를 정의함으로써 FSM은 모델이 주어진 구조를 준수하는 출력을 생성하도록 동적으로 안내합니다.
예를 들어, JSON을 생성하는 FSM에는 괄호 열기, 키 작성, 값 작성, 괄호 닫기에 대한 상태가 포함될 수 있습니다. FSM은 값을 작성하기 전에 괄호를 닫지 않는 것처럼 전이가 논리적인 순서로 발생하도록 보장합니다. 이를 통해 후처리 없이 출력의 구조적 무결성이 보장됩니다.
FSM은 구조화된 데이터 추출, 코드 생성, 응답 형식 지정과 같은 애플리케이션에서 특히 가치가 있습니다. 각 상태에 대한 유효한 전이를 사전 계산함으로써 FSM을 효율적으로 구현하여 런타임 오버헤드를 최소화할 수 있습니다. 이러한 효율성은 실시간 제약 조건 적용과 결합되어 FSM이 유효하면서도 문맥적으로 정확한 출력을 생성할 수 있게 합니다.
예시: 유효한 숫자 생성
FSM 기반 생성을 설명하기 위해, 작업이 유효한 숫자를 생성하는 것인 실제 예시를 살펴보겠습니다. 규칙은 숫자가 오직 숫자만 포함해야 하며, 선택적으로 단일 소수점을 포함할 수 있다고 지정합니다.
그림: 유효한 숫자 생성의 FSM
FSM은 State 0에서 시작하며, 여기서 유효한 토큰에는 모든 숫자 또는 소수점이 포함됩니다. 시스템이 1과 같은 숫자를 생성하면 State 1로 전이됩니다. 이 상태에서는 추가 숫자가 허용되거나, 소수점이 생성되면 FSM이 State 2로 전이될 수 있습니다. State 2에서는 여러 소수점이 규칙을 위반하므로 숫자만 유효합니다. FSM은 생성된 시퀀스를 기반으로 상태와 유효한 토큰을 동적으로 조정하여 출력이 지정된 형식을 준수하도록 보장합니다.
이 예시는 FSM이 실시간으로 제약 조건을 적용하는 방식을 보여줍니다. 주어진 작업에 대한 상태와 전이를 정의함으로써, 후처리나 수동 검증 없이 구조화된 출력을 생성할 수 있는 견고한 시스템을 만들 수 있습니다.
Guided Sampling과 Vector Database 결합
Guided sampling은 vector database와 결합될 때 그 잠재력을 최대한 발휘합니다. Milvus와 같은 이러한 특화된 데이터베이스는 고차원 벡터 임베딩을 효율적으로 저장, 관리, 검색하도록 설계되었습니다. Guided sampling과 vector database는 함께 비정형 데이터를 처리하면서 의미적으로 관련 있고 구조적으로 정밀한 출력을 생성하는 강력한 프레임워크를 만듭니다. 이 두 구성 요소가 AI 애플리케이션을 향상시키기 위해 어떻게 함께 작동하는지 살펴보겠습니다.
의미론적 기반으로서의 Vector Database
Vector database는 의미론적 검색을 포함하는 애플리케이션에서 기초 계층 역할을 합니다. 앞서 보았듯이, 딥러닝 모델이 생성한 임베딩은 vector database 내의 고차원 공간에 저장되며, 점들 사이의 거리는 의미론적 관계를 나타냅니다.
사용자가 쿼리를 만들면, 데이터베이스 임베딩을 생성한 동일한 모델을 사용하여 임베딩으로 변환됩니다. 그런 다음 데이터베이스는 유사도 검색을 수행하여 쿼리와 가장 관련 있는 임베딩을 찾습니다. 이 검색 프로세스는 쿼리가 정확한 키워드를 사용하지 않더라도 시스템이 문맥적으로 의미 있는 결과를 제공할 수 있게 합니다.
Guided Sampling으로 구조 추가
Vector database가 의미적으로 관련 있는 정보를 검색하는 반면, guided sampling은 출력이 특정 형식이나 제약 조건을 준수하도록 보장합니다. 관련 임베딩을 검색한 후, 이는 대규모 언어 모델(LLM)에 입력으로 전달됩니다. Guided sampling이 없으면 LLM은 형식이 잘못된 JSON이나 유효하지 않은 XML처럼 필요한 구조에서 벗어나는 응답을 생성할 수 있습니다. Guided sampling은 토큰 선택 과정에서 규칙을 동적으로 적용하여 이 문제를 해결합니다.
이 통합의 실제 애플리케이션
Vector database와 guided sampling의 조합은 다양한 산업 전반에 걸쳐 폭넓은 애플리케이션을 가지고 있습니다:
코딩 어시스턴트: 개발자가 AI 기반 코딩 어시스턴트에 쿼리하면, 시스템은 관련 코드 스니펫이나 문서 임베딩을 검색합니다. Guided sampling은 출력된 코드가 올바른 구문과 형식을 준수하도록 보장하여 수동 수정의 필요성을 줄입니다.
정보 추출 시스템: 이러한 시스템은 대규모 데이터셋을 분석하여 이름, 날짜, 위치와 같은 구조화된 정보를 추출합니다. 벡터 데이터베이스는 관련 데이터 세그먼트를 검색하고, 가이드 샘플링은 출력을 JSON과 같은 사전 정의된 스키마로 형식화합니다.
특화 도메인용 챗봇: 예를 들어 의료 또는 법률 도메인에서 챗봇은 의미적으로 유사한 사례 연구나 문서를 검색합니다. 가이드 샘플링은 생성된 응답이 엄격한 법률 또는 의료 형식 표준을 준수하도록 보장합니다.
제약 샘플링 구현 도구: Outlines와 BAML
여러 도구가 제약 샘플링 기법의 구현을 단순화합니다. 예를 들어 Outlines library는 제약 조건을 정의하고 구조화된 출력을 생성하기 위한 Python 기반 프레임워크를 제공합니다. 이를 통해 개발자는 텍스트 생성 중에 JSON 스키마나 정규식 패턴과 같은 규칙을 직접 적용할 수 있습니다. 마찬가지로 BAML은 LLM 기반 애플리케이션을 작성하고 테스트하기 위한 도메인 특화 언어를 제공하여, 제약 조건을 정의하고 출력을 검증하는 과정을 간소화합니다.
Outlines 라이브러리를 사용하여 제약 샘플링을 적용하는 방법을 살펴보겠습니다:
필요한 라이브러리를 설치하는 것부터 시작하세요:
pip install outlines transformers datasets
outlines 라이브러리는 구조화된 출력을 생성할 수 있게 해줍니다. transformers 라이브러리는 사전 학습된 모델을 로드할 수 있게 해줍니다. datasets 라이브러리는 outlines 라이브러리의 의존성입니다.
환경이 준비되었으니 코딩을 시작해 보겠습니다.
import outlines
import transformers
# Load the model
model = outlines.models.transformers("gpt2-medium")
# For text generation
generator = outlines.generate.text(model)
# Example 1: Basic Continuation
prompt = "Is 1+1=2? "
result = generator(prompt, max_tokens=30)
print("Unguided output:", result)
# Example 2: Structured Generation with Regex
guided_output = outlines.generate.regex(model, r"([Yy]es|[Nn]o|[Nn]ever|[Aa]lways)")(
prompt, max_tokens=30
)
print("Guided output:", guided_output)
# Example 3: Numerical Regex Constraint
prompt = "In what year was Noam Chomsky born?n"
guided_output_year = outlines.generate.regex(model, r"19[0-9]{2}")(
prompt, max_tokens=30
)
print("Guided output (year):", guided_output_year)
위 코드에서는 먼저 설치한 라이브러리를 가져온 다음, 텍스트 생성을 위해 GPT-2 medium 모델을 로드합니다. 처음에는 프롬프트 Is 1+1=2?에 대한 비가이드 응답을 생성하여 기본 텍스트 생성을 보여줍니다. 다음으로, 정규식을 사용해 모델이 Yes, No, Never, 또는 Always와 같은 응답만 생성하도록 유도하여 출력이 특정 답변 형식을 따르도록 보장합니다. 마지막으로, Noam Chomsky의 출생 연도를 대상으로 네 자리 연도를 추출하기 위해 정규식 제약 조건 r"19[0-9]{2}"를 구현합니다. 다음은 샘플 출력입니다:
그림: Outlines 라이브러리를 사용한 제약 샘플링의 출력
이는 특정 정보 추출 작업에 맞춘 자유 형식 및 구조화된 텍스트 생성 모두에 대한 모델의 역량을 보여줍니다.
결론
Stefan은 제약 샘플링과 FSM이 실제 애플리케이션에서 대규모 언어 모델을 더 신뢰할 수 있게 만드는 데 있어 중요한 발전을 의미한다는 점을 훌륭하게 보여주었습니다. 구조적 일관성을 강제하고 Outlines 및 벡터 데이터베이스와 같은 도구를 활용함으로써, 이제 우리는 유연성과 정밀성을 결합한 시스템을 구축할 수 있습니다. 이 분야가 발전함에 따라 이러한 기법은 비정형 데이터 처리와 구조화된 출력 생성 사이의 간극을 메우는 데 핵심적인 역할을 하며, AI 기반 애플리케이션의 새로운 가능성을 열어줄 것입니다.
자세한 내용은 YouTube에서 Stefan의 강연을 시청하세요.
계속 읽기

My Wife Wanted Dior. I Spent $600 on Claude Code to Vibe-Code a 2M-Line Database Instead.
Write tests, not code reviews. How a test-first workflow with 6 parallel Claude Code sessions turns a 2M-line C++ codebase into a daily shipping pipeline.

How to Build an Enterprise-Ready RAG Pipeline on AWS with Bedrock, Zilliz Cloud, and LangChain
Build production-ready enterprise RAG with AWS Bedrock, Nova models, Zilliz Cloud, and LangChain. Complete tutorial with deployable code.

8 Latest RAG Advancements Every Developer Should Know
Explore eight advanced RAG variants that can solve real problems you might be facing: slow retrieval, poor context understanding, multimodal data handling, and resource optimization.


