본문 바로가기
C.W.K.
Stream
Lesson 02 of 06 · published

학습 자료 준비 — JSONL, 템플릿, 청소

~16 min · data, jsonl, chat-template

Level 0호기심
0 XP0/51 lessons0/15 achievements
0/100 XP to next level100 XP to go0% complete

깨끗한 작은 자료가 지저분한 큰 자료를 이겨

파인튜닝 품질을 가장 잘 예측하는 건 순위도, 옵티마이저도, 반복 횟수도 아니라 학습 자료야. 잘 정리한 200개 예제로 학습한 7B 모델이 지저분한 2,000개를 먹은 같은 모델보다 대부분의 후속 작업에서 낫다. 하이퍼파라미터보다 자료에 시간을 더 써.

mlx-lm이 받는 파일

mlx-lm은 한 줄에 JSON 객체 하나를 적는 JSONL을 써. --data가 가리키는 폴더에는 다음 이름을 둬.

  • train.jsonl — 필수인 학습 예제야.
  • valid.jsonl — 필수인 검증 예제야. --steps-per-eval마다 검증 손실을 계산해.
  • test.jsonl — 선택 사항이고 학습 뒤 --test 평가에 써.

각 줄은 OpenAI 채팅과 같은 messages 배열을 가진 채팅 형식이나, 오래된 문장 완성 학습용 promptcompletion 쌍을 가진 완성 형식이 될 수 있어.

채팅 형식을 기본으로 써

각 객체에 messages를 두고 메시지마다 system, user, assistant 중 하나인 rolecontent를 넣어. mlx-lm이 학습 때 모델의 채팅 템플릿을 적용하므로 추론 때와 같은 모양을 보게 돼. 채팅 학습 기반 모델이라면 이건 선택이 아니야. 템플릿 없이 학습하면 추론에서 일관되게 동작하지 않아.

학습 전에 꼭 청소해

  1. 중복 제거. 같거나 거의 같은 예제는 편향을 만들고 자료 수만 부풀려.
  2. 길이 거르기. 신호가 없는 지나치게 짧은 예제와 --max-seq-length를 넘어 생각 중간이 잘리는 긴 예제를 빼.
  3. 품질 거르기. 판단상 하위 5%만 눈으로 훑어도 오타, 깨진 형식, 엉뚱한 내용을 많이 잡아.
  4. 누수 없는 분할. 검증과 시험 자료를 학습 자료와 겹치지 않게 떼어. 보통 무작위 분할이면 되고 아주 작다면 작업 꼬리표별 비율을 맞춰.

연습용 실제 자료가 필요하다면

mlx-community/wikisql은 mlx-lm에서 바로 쓰는 고전적인 SQL 생성 시연 자료야. 자기 작업이라면 잘 다듬은 100개 예제도 충분히 존중할 만한 출발점이야.

Code

채팅 형식 JSONL — 표준 학습 자료 모양·python
# Each line is one example with a 'messages' array.
import json

examples = [
    {
        "messages": [
            {"role": "system",    "content": "You are a SQL expert."},
            {"role": "user",      "content": "How many users joined in 2024?"},
            {"role": "assistant", "content": "SELECT COUNT(*) FROM users WHERE YEAR(joined_at) = 2024;"},
        ]
    },
    {
        "messages": [
            {"role": "system",    "content": "You are a SQL expert."},
            {"role": "user",      "content": "List all products under $10."},
            {"role": "assistant", "content": "SELECT * FROM products WHERE price < 10;"},
        ]
    },
]

with open("./my-data/train.jsonl", "w") as f:
    for ex in examples:
        f.write(json.dumps(ex) + "\n")

# Then point mlx-lm at the directory:
#   python -m mlx_lm lora --model ... --train --data ./my-data
빠른 중복 제거 + 길이 필터·python
import json, hashlib

def line_hash(ex):
    # Hash the messages content for dedup
    return hashlib.md5(json.dumps(ex["messages"], sort_keys=True).encode()).hexdigest()

def total_chars(ex):
    return sum(len(m["content"]) for m in ex["messages"])

seen = set()
kept, dropped = [], 0
for line in open("./my-data/train.jsonl"):
    ex = json.loads(line)
    h = line_hash(ex)
    n = total_chars(ex)
    if h in seen or n < 50 or n > 8000:   # adjust thresholds for your task
        dropped += 1
        continue
    seen.add(h)
    kept.append(ex)

print(f"kept {len(kept)}, dropped {dropped}")
with open("./my-data/train.cleaned.jsonl", "w") as f:
    for ex in kept:
        f.write(json.dumps(ex) + "\n")

External links

Exercise

SQL 질의, 정규식, 재치 있는 하이쿠, 기술 RSS 요약처럼 잘 아는 좁은 영역을 골라. system, user, assistant가 든 채팅 JSONL 예제 30개를 직접 만들고 train.jsonl에 저장한 뒤 5개는 valid.jsonl로 떼어둬. 두 번째 코드 블록으로 중복과 길이를 걸러. 이 일의 대부분이 학습보다 큐레이션이라는 감각을 잡아.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.