C.W.K.
Stream
Lesson 02 of 06 · published

Training data 준비 — JSONL, template, 청소

~16 min · data, jsonl, chat-template

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

나쁜 데이터가 매번 loss 곡선에서 작은 모델 이김

Fine-tuning 품질의 가장 큰 단일 예측자는 학습 데이터, rank 아니고, optimizer 아니고, iteration 수 아냐. 200 개 깨끗하고, 잘-format 된 예제 가진 7B 모델이 2000 개 지저분한 예제 가진 같은 모델보다 대부분 downstream 작업 이김. 하이퍼파라미터 튜닝보다 데이터에 더 많은 시간 써.

mlx-lm 이 기대하는 형식

mlx-lm 이 JSONL 원해 — 줄 당 하나의 JSON 객체. --data 가리키는 데이터 디렉토리에 두 파일 명명 convention 살아:

  • train.jsonl — 필수. 학습 예제.
  • valid.jsonl — 필수. --steps-per-eval iter 마다 val loss 계산 위해 사용된 검증 예제.
  • test.jsonl — 옵션. 학습 후 평가 위해 --test 가 사용.

각 .jsonl 줄 안에 mlx-lm 이 두 모양 받음 — chat 형식 (OpenAI 의 chat-completion 같은 messages 배열) 또는 completion 형식 (오래된 non-chat 학습용 prompt + completion 쌍).

Chat 형식 — 맞는 기본

각 줄은 messages 필드 가진 JSON 객체. 각 메시지는 role (system / user / assistant) 와 content 가짐. mlx-lm 이 학습 시간에 모델의 chat template 적용 — 그래서 format 이 추론에서 모델이 볼 거와 일치. Chat-tuned base 모델엔 non-negotiable — chat-templated 형태로 학습하지 않으면 결과 fine-tune 이 추론에서 나쁘게 동작.

모두가 건너뛰는 청소 단계

어떤 데이터셋이든 (자기 거 또는 HF 에서 pull 한 거) 학습 전에 이 pass 들 해:

  1. 중복 제거. 동일 또는 거의-동일 예제가 모델 bias 시키고 명백한 학습-셋 크기 부풀림.
  2. 길이-필터. 터무니없이 짧거나 (시그널 없음) --max-seq-length 보다 긴 (잘림, 종종 생각 중간) 예제 drop.
  3. 품질-필터. 너 판단의 하위 5% 예제만 빠르게 눈으로 봐도 많이 잡아 — 오타, 깨진 format, off-topic noise.
  4. 누수 없이 split. 같은 데이터셋에서 검증과 테스트 셋 hold out; 학습과 disjoint 확인. 대부분 케이스엔 random split 괜찮; 매우 작은 데이터셋엔 작업의 label 로 stratify.

가지고 놀 real-world 데이터셋 원하면

Hugging Face 의 mlx-community org 가 mlx-lm 와 out of the box 동작하는 작은 데이터셋 몇 개 호스팅 — mlx-community/wikisql (SQL 생성, 클래식) 이 canonical demo 셋. 자기 작업엔 잘-큐레이트 된 100 예제도 존중할 만한 시작점.

Code

Chat-format JSONL — canonical 학습 데이터 모양·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 query, regex 패턴, 재치 있는 hai-ku, tech RSS 요약, narrow 한 무엇이든. 30 개의 chat-format JSONL 예제 손으로 박아 (system + user + assistant). train.jsonl 로 저장, 5 개를 valid.jsonl 로 hold out. 두 번째 코드 블록의 dedup + 길이 필터 돌려. 운동은 작업 느끼는 것 — 대부분이 학습이 아니라 큐레이션.

Progress

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

댓글 0

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

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