배울 내용
- Weave 및 W&B Inference 설정
- 자동 Tracing이 포함된 기본 LLM 애플리케이션 빌드
- 여러 모델 비교
- 데이터셋에서 모델 성능 평가
- Weave UI에서 결과 보기
사전 요구 사항
- W&B 계정
- Python 3.8+ 또는 Node.js 18+
- 필수 패키지가 설치되어 있어야 합니다:
- Python:
pip install weave openai - TypeScript:
npm install weave openai
- Python:
- OpenAI API 키를 환경 변수로 설정해야 합니다
첫 번째 LLM call 트레이스하기
- LLM call을 자동으로 트레이스합니다
- 입력, 출력, 지연 시간, 토큰 사용량을 로깅합니다
- Weave UI에서 트레이스를 확인할 수 있는 링크를 제공합니다
- Python
- TypeScript
import weave
import openai
# Weave를 초기화합니다 - your-team/your-project로 바꾸세요
weave.init("<team-name>/inference-quickstart")
# W&B Inference를 가리키는 OpenAI 호환 클라이언트를 생성합니다
client = openai.OpenAI(
base_url='https://api.inference.wandb.ai/v1',
api_key="YOUR_WANDB_API_KEY", # 실제 API 키로 바꾸세요
project="<team-name>/my-first-weave-project", # 사용량 추적에 필요합니다
)
# 트레이싱을 활성화하려면 함수에 데코레이터를 적용합니다. 표준 OpenAI 클라이언트를 사용하세요
@weave.op()
def ask_llama(question: str) -> str:
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": question}
],
)
return response.choices[0].message.content
# 함수를 호출합니다 - Weave가 모든 것을 자동으로 트레이스합니다
result = ask_llama("What are the benefits of using W&B Weave for LLM development?")
print(result)
import * as weave from 'weave';
import OpenAI from 'openai';
// Weave를 초기화합니다 - "<>"로 둘러싸인 값을 직접 사용하려는 값으로 바꾸세요.
await weave.init("<team-name>/inference-quickstart")
// W&B Inference를 가리키는 OpenAI 호환 클라이언트를 생성합니다
const client = new OpenAI({
baseURL: 'https://api.inference.wandb.ai/v1', // W&B Inference 엔드포인트
apiKey: process.env.WANDB_API_KEY || 'YOUR_WANDB_API_KEY', // API 키로 바꾸거나 WANDB_API_KEY 환경 변수를 설정하세요
});
// 트레이싱을 활성화하려면 weave.op으로 함수를 래핑합니다
const askLlama = weave.op(async function askLlama(question: string): Promise<string> {
const response = await client.chat.completions.create({
model: 'meta-llama/Llama-3.1-70B-Instruct',
messages: [
{ role: 'system', content: 'You are a helpful assistant.' },
{ role: 'user', content: question }
],
});
return response.choices[0].message.content || '';
});
// 함수를 호출합니다 - Weave가 모든 것을 자동으로 트레이스합니다
const result = await askLlama('What are the benefits of using W&B Weave for LLM development?');
console.log(result);
텍스트 요약 애플리케이션 만들기
- Python
- TypeScript
import weave
import openai
# Weave 초기화 - "<>"로 묶인 값을 본인의 값으로 교체하세요.
weave.init("<team-name>/inference-quickstart")
client = openai.OpenAI(
base_url='https://api.inference.wandb.ai/v1',
api_key="YOUR_WANDB_API_KEY", # 실제 API 키로 교체하세요
project="<team-name>/my-first-weave-project", # 사용량 추적에 필요합니다
)
@weave.op()
def extract_key_points(text: str) -> list[str]:
"""Extract key points from a text."""
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "Extract 3-5 key points from the text. Return each point on a new line."},
{"role": "user", "content": text}
],
)
# 빈 줄을 제외하고 응답을 반환합니다
return [line for line in response.choices[0].message.content.strip().splitlines() if line.strip()]
@weave.op()
def create_summary(key_points: list[str]) -> str:
"""Create a concise summary based on key points."""
points_text = "\n".join(f"- {point}" for point in key_points)
response = client.chat.completions.create(
model="meta-llama/Llama-3.1-8B-Instruct",
messages=[
{"role": "system", "content": "Create a one-sentence summary based on these key points."},
{"role": "user", "content": f"Key points:\n{points_text}"}
],
)
return response.choices[0].message.content
@weave.op()
def summarize_text(text: str) -> dict:
"""Main summarization pipeline."""
key_points = extract_key_points(text)
summary = create_summary(key_points)
return {
"key_points": key_points,
"summary": summary
}
# 샘플 텍스트로 사용해 보세요
sample_text = """
The Apollo 11 mission was a historic spaceflight that landed the first humans on the Moon
on July 20, 1969. Commander Neil Armstrong and lunar module pilot Buzz Aldrin descended
to the lunar surface while Michael Collins remained in orbit. Armstrong became the first
person to step onto the Moon, followed by Aldrin 19 minutes later. They spent about
two and a quarter hours together outside the spacecraft, collecting samples and taking photographs.
"""
result = summarize_text(sample_text)
print("Key Points:", result["key_points"])
print("\nSummary:", result["summary"])
import * as weave from 'weave';
import OpenAI from 'openai';
// Weave 초기화 - your-team/your-project로 교체하세요
await weave.init('<team-name>/inference-quickstart');
const client = new OpenAI({
baseURL: 'https://api.inference.wandb.ai/v1',
apiKey: process.env.WANDB_API_KEY || 'YOUR_WANDB_API_KEY', // API 키로 교체하거나 WANDB_API_KEY 환경 변수를 설정하세요
});
const extractKeyPoints = weave.op(async function extractKeyPoints(text: string): Promise<string[]> {
const response = await client.chat.completions.create({
model: 'meta-llama/Llama-3.1-8B-Instruct',
messages: [
{ role: 'system', content: 'Extract 3-5 key points from the text. Return each point on a new line.' },
{ role: 'user', content: text }
],
});
// 빈 줄을 제외한 응답을 반환합니다
const content = response.choices[0].message.content || '';
return content.split('\n').map(line => line.trim()).filter(line => line.length > 0);
});
const createSummary = weave.op(async function createSummary(keyPoints: string[]): Promise<string> {
const pointsText = keyPoints.map(point => `- ${point}`).join('\n');
const response = await client.chat.completions.create({
model: 'meta-llama/Llama-3.1-8B-Instruct',
messages: [
{ role: 'system', content: 'Create a one-sentence summary based on these key points.' },
{ role: 'user', content: `Key points:\n${pointsText}` }
],
});
return response.choices[0].message.content || '';
});
const summarizeText = weave.op(async function summarizeText(text: string): Promise<{key_points: string[], summary: string}> {
const keyPoints = await extractKeyPoints(text);
const summary = await createSummary(keyPoints);
return {
key_points: keyPoints,
summary: summary
};
});
// 샘플 텍스트로 사용해 보세요
const sampleText = `
The Apollo 11 mission was a historic spaceflight that landed the first humans on the Moon
on July 20, 1969. Commander Neil Armstrong and lunar module pilot Buzz Aldrin descended
to the lunar surface while Michael Collins remained in orbit. Armstrong became the first
person to step onto the Moon, followed by Aldrin 19 minutes later. They spent about
two and a quarter hours together outside the spacecraft, collecting samples and taking photographs.
`;
const result = await summarizeText(sampleText);
console.log('Key Points:', result.key_points);
console.log('\nSummary:', result.summary);
여러 모델 비교
- Python
- TypeScript
import weave
import openai
# Weave를 초기화합니다. your-team/your-project로 바꾸세요
weave.init("<team-name>/inference-quickstart")
client = openai.OpenAI(
base_url='https://api.inference.wandb.ai/v1',
api_key="YOUR_WANDB_API_KEY", # 실제 API 키로 바꾸세요
project="<team-name>/my-first-weave-project", # 사용 추적에 필요합니다
)
# 서로 다른 LLM을 비교하기 위한 Model 클래스를 정의합니다
class InferenceModel(weave.Model):
model_name: str
@weave.op()
def predict(self, question: str) -> str:
response = client.chat.completions.create(
model=self.model_name,
messages=[
{"role": "user", "content": question}
],
)
return response.choices[0].message.content
# 서로 다른 모델 인스턴스를 생성합니다
llama_model = InferenceModel(model_name="meta-llama/Llama-3.1-8B-Instruct")
deepseek_model = InferenceModel(model_name="deepseek-ai/DeepSeek-V3.1")
# 응답을 비교합니다
test_question = "Explain quantum computing in one paragraph for a high school student."
print("Llama 3.1 8B response:")
print(llama_model.predict(test_question))
print("\n" + "="*50 + "\n")
print("DeepSeek V3 response:")
print(deepseek_model.predict(test_question))
import * as weave from 'weave';
import OpenAI from 'openai';
// Weave를 초기화합니다. your-team/your-project로 바꾸세요
await weave.init("<team-name>/inference-quickstart")
const client = new OpenAI({
baseURL: 'https://api.inference.wandb.ai/v1',
apiKey: process.env.WANDB_API_KEY || 'YOUR_WANDB_API_KEY', // API 키로 바꾸거나 WANDB_API_KEY 환경 변수를 설정하세요
});
// weave.op을 사용해 모델 함수를 생성합니다 (TypeScript에서는 weave.Model이 지원되지 않음)
function createModel(modelName: string) {
return weave.op(async function predict(question: string): Promise<string> {
const response = await client.chat.completions.create({
model: modelName,
messages: [
{ role: 'user', content: question }
],
});
return response.choices[0].message.content || '';
});
}
// 서로 다른 모델 인스턴스를 생성합니다
const llamaModel = createModel('meta-llama/Llama-3.1-8B-Instruct');
const deepseekModel = createModel('deepseek-ai/DeepSeek-V3.1');
// 응답을 비교합니다
const testQuestion = 'Explain quantum computing in one paragraph for a high school student.';
console.log('Llama 3.1 8B response:');
console.log(await llamaModel(testQuestion));
console.log('\n' + '='.repeat(50) + '\n');
console.log('DeepSeek V3 response:');
console.log(await deepseekModel(testQuestion));
모델 성능 평가
EvaluationLogger를 사용해 Q&A 작업에서 모델의 성능을 평가합니다. 그러면 자동 집계, 토큰 사용량 수집, UI에서의 다양한 비교 기능을 포함한 구조화된 평가 추적이 제공됩니다.
이전 섹션에서 사용한 스크립트에 다음 코드를 추가합니다:
- Python
- TypeScript
from typing import Optional
from weave import EvaluationLogger
# 간단한 데이터셋 생성
dataset = [
{"question": "What is 2 + 2?", "expected": "4"},
{"question": "What is the capital of France?", "expected": "Paris"},
{"question": "Name a primary color", "expected_one_of": ["red", "blue", "yellow"]},
]
# scorer 정의
@weave.op()
def accuracy_scorer(expected: str, output: str, expected_one_of: Optional[list[str]] = None) -> dict:
"""모델 출력의 정확도를 채점합니다."""
output_clean = output.strip().lower()
if expected_one_of:
is_correct = any(option.lower() in output_clean for option in expected_one_of)
else:
is_correct = expected.lower() in output_clean
return {"correct": is_correct, "score": 1.0 if is_correct else 0.0}
# Weave의 EvaluationLogger를 사용하여 모델 평가
def evaluate_model(model: InferenceModel, dataset: list[dict]):
"""Weave의 내장 평가 프레임워크를 사용하여 데이터셋에 대한 평가를 실행합니다."""
# 토큰 사용량을 캡처하려면 모델 호출 전에 EvaluationLogger를 초기화하세요
# W&B Inference에서 비용을 추적할 때 특히 중요합니다
# 모델 이름을 유효한 형식으로 변환합니다 (영숫자가 아닌 문자를 언더스코어로 대체)
safe_model_name = model.model_name.replace("/", "_").replace("-", "_").replace(".", "_")
eval_logger = EvaluationLogger(
model=safe_model_name,
dataset="qa_dataset"
)
for example in dataset:
# 모델 예측 결과 조회
output = model.predict(example["question"])
# 예측 로깅
pred_logger = eval_logger.log_prediction(
inputs={"question": example["question"]},
output=output
)
# 출력 채점
score = accuracy_scorer(
expected=example.get("expected", ""),
output=output,
expected_one_of=example.get("expected_one_of")
)
# 점수 로깅
pred_logger.log_score(
scorer="accuracy",
score=score["score"]
)
# 이 예측에 대한 로깅 완료
pred_logger.finish()
# 요약 로깅 - Weave가 정확도 점수를 자동으로 집계합니다
eval_logger.log_summary()
print(f"{model.model_name} (로깅 이름: {safe_model_name}) 평가가 완료되었습니다. Weave UI에서 결과를 확인하세요.")
# 여러 모델 비교 - Weave 평가 프레임워크의 핵심 기능
models_to_compare = [
llama_model,
deepseek_model,
]
for model in models_to_compare:
evaluate_model(model, dataset)
# Weave UI에서 Evals 탭으로 이동하여 모델 간 결과를 비교하세요
import { EvaluationLogger } from 'weave';
// Create a simple dataset
interface DatasetExample {
question: string;
expected?: string;
expected_one_of?: string[];
}
const dataset: DatasetExample[] = [
{ question: 'What is 2 + 2?', expected: '4' },
{ question: 'What is the capital of France?', expected: 'Paris' },
{ question: 'Name a primary color', expected_one_of: ['red', 'blue', 'yellow'] },
];
// Define a scorer
const accuracyScorer = weave.op(function accuracyScorer(args: {
expected: string;
output: string;
expected_one_of?: string[];
}): { correct: boolean; score: number } {
const outputClean = args.output.trim().toLowerCase();
let isCorrect: boolean;
if (args.expected_one_of) {
isCorrect = args.expected_one_of.some(option =>
outputClean.includes(option.toLowerCase())
);
} else {
isCorrect = outputClean.includes(args.expected.toLowerCase());
}
return { correct: isCorrect, score: isCorrect ? 1.0 : 0.0 };
});
// Evaluate a model using Weave's EvaluationLogger
async function evaluateModel(
model: (question: string) => Promise<string>,
modelName: string,
dataset: DatasetExample[]
): Promise<void> {
// Initialize EvaluationLogger BEFORE calling the model to capture token usage
// This is especially important for W&B Inference to track costs
// Convert model name to a valid format (replace non-alphanumeric chars with underscores)
const safeModelName = modelName.replace(/\//g, '_').replace(/-/g, '_').replace(/\./g, '_');
const evalLogger = new EvaluationLogger({
name: 'inference_evaluation',
model: { name: safeModelName },
dataset: 'qa_dataset'
});
for (const example of dataset) {
// Get model prediction
const output = await model(example.question);
// Log the prediction
const predLogger = evalLogger.logPrediction(
{ question: example.question },
output
);
// Score the output
const score = await accuracyScorer({
expected: example.expected || '',
output: output,
expected_one_of: example.expected_one_of
});
// Log the score
predLogger.logScore('accuracy', score.score);
// Finish logging for this prediction
predLogger.finish();
}
// Log summary - Weave automatically aggregates the accuracy scores
await evalLogger.logSummary();
console.log(`Evaluation complete for ${modelName} (logged as: ${safeModelName}). View results in the Weave UI.`);
}
// Compare multiple models - a key feature of Weave's evaluation framework
const modelsToCompare = [
{ model: llamaModel, name: 'meta-llama/Llama-3.1-8B-Instruct' },
{ model: deepseekModel, name: 'deepseek-ai/DeepSeek-V3.1' },
];
for (const { model, name } of modelsToCompare) {
await evaluateModel(model, name, dataset);
}
// In the Weave UI, navigate to the Evals tab to compare results across models
- 모든 LLM call의 타임라인 검토
- 각 오퍼레이션의 입력과 출력 확인
- 토큰 사용량과 예상 비용 확인(EvaluationLogger가 자동으로 수집)
- 지연 시간과 성능 메트릭 분석
- Evals 탭으로 이동해 집계된 평가 결과 확인
- Compare 기능을 사용해 서로 다른 모델의 성능 비교 및 분석
- 특정 예제를 넘겨 보면서 동일한 입력에 대해 서로 다른 모델이 어떻게 수행되었는지 확인
사용 가능한 모델
다음 단계
- 플레이그라운드 사용하기: Weave 플레이그라운드에서 모델을 대화형으로 사용해 보기
- 평가 구축하기: LLM 애플리케이션의 체계적인 평가에 대해 알아보세요
- 다른 인테그레이션 사용해 보기: Weave는 OpenAI, Anthropic 등 다양한 서비스와 연동됩니다