Pixeltable로 증가형 프롬프트 엔지니어링과 모델 비교하기

Pixeltable로 증가형 프롬프트 엔지니어링과 모델 비교하기

Pixeltable로 Mistral AI 모델을 대상으로 반복적인 프롬프트 엔지니어링과 모델 비교를 하는 방법을 보여주는 노트북이에요. 영속 스토리지, 증가형 업데이트를 활용하고, 여러 프롬프트와 모델을 쉽게 벤치마킹합니다.

출처: 문서

본문

Pixeltable은 멀티모달 AI를 위한 선언적(declarative)·증가형(incremental) 접근을 제공하는 데이터 인프라입니다. 이 노트북은 프롬프트 엔지니어링 & 모델 비교를 주제로 합니다.

1. 설정과 설치

%pip install -qU pixeltable mistralai textblob nltk
import os
import getpass
import pixeltable as pxt
from pixeltable.functions.mistralai import chat_completions
from textblob import TextBlob
import nltk
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
import re
nltk.download('punkt', quiet=True)
nltk.download('stopwords', quiet=True)
nltk.download('punkt_tab', quiet=True)
if 'MISTRAL_API_KEY' not in os.environ:
    os.environ['MISTRAL_API_KEY'] = getpass.getpass('Mistral AI API Key:')

2. Pixeltable 테이블 만들고 예제 삽입

Pixeltable은 영속적이에요. Pandas 같은 인메모리 Python 라이브러리와 달리 Pixeltable은 데이터베이스라서, 노트북 커널을 리셋하거나 새 Python 세션을 시작해도 이전에 Pixeltable에 저장한 모든 데이터에 접근할 수 있습니다.

# Create a table to store prompts and results
pxt.drop_table('mistral_prompts', ignore_errors=True)
t = pxt.create_table('mistral_prompts', {
    'task': pxt.StringType(),
    'system': pxt.StringType(),
    'input_text': pxt.StringType()
})

# Insert sample data
t.insert([
    {'task': 'summarization',
     'system': 'Summarize the following text:',
     'input_text': 'Mistral AI is a French artificial intelligence (AI) research and development company that focuses on creating and applying AI technologies to various industries.'},
    {'task': 'sentiment',
     'system': 'Analyze the sentiment of this text:',
     'input_text': 'I love using Mistral for my AI projects! They provide great LLMs and it is really easy to work with.'},
    {'task': 'question_answering',
     'system': 'Answer the following question:',
     'input_text': 'What are the main benefits of using Mistral AI over other LLMs providers?'}
])

3. Mistral 추론 함수 실행하기

계산 컬럼(computed column)을 만들어 Pixeltable이 Mistral chat_completions 함수를 실행하고 출력을 저장하도록 합니다. 계산 컬럼은 테이블의 영구적인 부분이므로, 새 데이터가 들어올 때마다 자동으로 갱신됩니다. 이 예제에서는 open_mistral_nemo와 mistral_medium 모델을 실행해 각각의 컬럼에 출력을 만듭니다.

# We are referencing columns from the 'mistral_prompts' table to dynamically compose the message for the Inference API.
msgs = [
    {'role': 'system', 'content': t.system},
    {'role': 'user', 'content': t.input_text}
]

# Run inference with open-mistral-nemo model
t['open_mistral_nemo'] = chat_completions(
    messages=msgs,
    model='open-mistral-nemo',
    max_tokens=300,
    top_p=0.9,
    temperature=0.7
)

# Run inference with mistral-medium model
t['mistral_medium'] = chat_completions(
    messages=msgs,
    model='mistral-medium',
    max_tokens=300,
    top_p=0.9,
    temperature=0.7
)

각 응답 컬럼은 JSON 컬럼 타입이에요. JSON 경로 표현식을 사용해 관련 데이터를 추출하고 추가 계산 컬럼으로 만들 수 있습니다.

# Extract the response content as a string (by default JSON)
t['omn_response'] = t.open_mistral_nemo.choices[0].message.content.astype(pxt.StringType())
t['ml_response'] = t.mistral_medium.choices[0].message.content.astype(pxt.StringType())
# Display the responses
t.select(t.omn_response, t.ml_response).collect()

테이블의 다양한 컬럼에 걸쳐 데이터가 어떻게 계산되는지 확인할 수 있어요.

t

4. 사용자 정의 함수(UDF)로 추가 분석하기

UDF는 Pixeltable을 커스텀 Python 코드로 확장하게 해 줍니다. 워크플로에 어떤 계산이나 분석도 통합할 수 있어요. 여기서는 LLM 출력 품질에 대한 인사이트를 주는 두 가지 메트릭(감성 점수·가독성 점수)을 계산하는 UDF 세 개를 정의합니다.

@pxt.udf
def get_sentiment_score(text: str) -> float:
    return TextBlob(text).sentiment.polarity

@pxt.udf
def extract_keywords(text: str, num_keywords: int = 5) -> list:
    stop_words = set(stopwords.words('english'))
    words = word_tokenize(text.lower())
    keywords = [word for word in words if word.isalnum() and word not in stop_words]
    return sorted(set(keywords), key=keywords.count, reverse=True)[:num_keywords]

@pxt.udf
def calculate_readability(text: str) -> float:
    words = len(re.findall(r'\w+', text))
    sentences = len(re.findall(r'\w+[.!?]', text)) or 1
    average_words_per_sentence = words / sentences
    return 206.835 - 1.015 * average_words_per_sentence

비교하려는 각 모델에 대해, 만든 UDF로 메트릭을 새로운 계산 컬럼으로 추가합니다.

t['large_sentiment_score'] = get_sentiment_score(t.ml_response)
t['large_keywords'] = extract_keywords(t.ml_response)
t['large_readability_score'] = calculate_readability(t.ml_response)

t['open_sentiment_score'] = get_sentiment_score(t.omn_response)
t['open_keywords'] = extract_keywords(t.omn_response)
t['open_readability_score'] = calculate_readability(t.omn_response)

UDF를 정의해 계산 컬럼에 사용하면 Pixeltable이 이를 모든 관련 행에 자동 적용해요. 루프를 쓰거나 각 행에 함수를 수동 적용할 필요가 없습니다.

t.head(1)

행을 두 개 더 추가하면 Pixeltable이 계산 컬럼을 자동으로 채워줍니다.

t.insert([
    {
        'task': 'summarization',
        'system': 'Provide a concise summary of the following text in one sentence:',
        'input_text': 'Mistral AI is a company that develops AI models and has been in the news for its partnerships and latest models.'
    },
    {
        'task': 'translation',
        'system': 'Translate the following English text to French:',
        'input_text': 'Hello, how are you today?'
    }
])

특정 행·컬럼만 선택하고 싶다면 where()를 사용합니다.

t.select(t.task, t.omn_response, t.ml_response, t.large_readability_score, t.open_readability_score).where(t.task == 'summarization').collect()

5. 다른 프롬프트로 실험하기

Pixeltable의 스키마는 데이터 수집, 추론 API 호출, 메트릭 계산을 하나의 관점으로 보여주며 전체 워크플로를 반영합니다.

더 알아보기 (Learn more)

  • Pixeltable 공식 문서 — 멀티모달 AI용 데이터 인프라
  • pixeltable.functions.mistralai.chat_completions — Mistral 채팅 완성 추론 함수
  • pxt.create_table / 계산 컬럼 — 영속 테이블과 자동 갱신 컬럼
  • 모델: open-mistral-nemo, mistral-medium