การเตรียมชุดข้อมูลฝึกคุณภาพสูง
รวบรวม ทำความสะอาด และจัดรูปแบบข้อมูลที่ทำตามคำสั่งได้ในรูปแบบ Alpaca และ ShareGPT กำจัดข้อมูลซ้ำ และแบ่งเป็นชุดฝึกกับชุดตรวจสอบ
การเตรียมชุดข้อมูลฝึกคุณภาพสูง เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
ข้อมูลคือปัจจัยสำคัญที่สุดของการปรับแต่งแบบละเอียด
ในการปรับแต่งแบบละเอียด คุณภาพของข้อมูลฝึกสำคัญกว่าพารามิเตอร์ไฮเปอร์พารามิเตอร์ การเลือกสถาปัตยกรรม หรือเทคนิคการฝึกใด ๆ ตัวอย่างคุณภาพสูง 100 รายการให้ผลดีกว่าตัวอย่างคุณภาพปานกลาง 10,000 รายการ ข้อมูลขาเข้าเป็นอย่างไร ผลลัพธ์ขาออกก็เป็นเช่นนั้น — โมเดลที่ปรับแต่งแบบละเอียดจะทำซ้ำรูปแบบทั้งหมดที่มีอยู่ในข้อมูลของคุณอย่างตรงไปตรงมา รวมถึงข้อผิดพลาด อคติ และความไม่สม่ำเสมอของรูปแบบ การลงทุนกับคุณภาพข้อมูลคือการดำเนินการที่สร้างผลตอบแทนสูงที่สุดในโครงการปรับแต่งแบบละเอียดทุกโครงการ
รูปแบบการทำตามคำสั่ง
การปรับแต่งแบบละเอียดส่วนใหญ่สำหรับงานทำตามคำสั่งใช้ รูปแบบข้อความสนทนา ที่มีบทบาทของระบบ ผู้ใช้ และผู้ช่วย ส่วนเชื่อมต่อโปรแกรมสำหรับการปรับแต่งแบบละเอียดของ OpenAI ใช้ไฟล์ JSONL โดยแต่ละบรรทัดเป็นตัวอย่างการสนทนาที่สมบูรณ์ รูปแบบ Alpaca (คำสั่ง/ข้อมูลขาเข้า/ข้อมูลขาออก) และรูปแบบ ShareGPT (รายการการสนทนา) ก็ได้รับความนิยมอย่างแพร่หลายเช่นกัน โปรดเลือกรูปแบบที่ตรงกับกรอบการทำงานสำหรับการปรับแต่งแบบละเอียดที่คุณวางแผนจะใช้
import json
# OpenAI fine-tuning format (JSONL)
# Each line is one training example
openai_example = {
'messages': [
{'role': 'system', 'content': 'You are a JSON extraction agent.'},
{'role': 'user', 'content': 'Extract: "John Smith, age 32, from Seattle, joined 2023-01-15"'},
{'role': 'assistant', 'content': '{"name": "John Smith", "age": 32, "city": "Seattle", "join_date": "2023-01-15"}'}
]
}
# Alpaca format
alpaca_example = {
'instruction': 'Extract structured data from the following text.',
'input': 'John Smith, age 32, from Seattle, joined 2023-01-15',
'output': '{"name": "John Smith", "age": 32, "city": "Seattle", "join_date": "2023-01-15"}'
}
# Write as JSONL
with open('train.jsonl', 'w') as f:
f.write(json.dumps(openai_example) + '\n')
# Add more examples here...การรวบรวมข้อมูลฝึก: สามกลยุทธ์
มีกลยุทธ์หลักสามแบบสำหรับสร้างชุดข้อมูลสำหรับการปรับแต่งแบบละเอียด การสร้างโดยมนุษย์: ผู้เชี่ยวชาญเขียนตัวอย่างในอุดมคติด้วยตนเอง — คุณภาพสูงสุดแต่ช้าและมีค่าใช้จ่ายสูง การสร้างโดย LLM: โมเดลทรงพลัง (GPT-4o) สร้างตัวอย่าง จากนั้นมนุษย์ตรวจสอบความถูกต้อง — เร็วกว่าและถูกกว่ามาก และมีคุณภาพดีหากผ่านการตรวจสอบ การขุดข้อมูลจากบันทึก: แยกคู่ข้อมูลขาเข้า-ข้อมูลขาออกจากบันทึกการใช้งานจริงที่มีอยู่ แล้วกรองหาตัวอย่างคุณภาพสูงโดยใช้สัญญาณคุณภาพ เช่น การให้คะแนนของผู้ใช้หรือการให้คะแนนโดย LLM ในฐานะผู้ตัดสิน
from openai import OpenAI
client = OpenAI()
def generate_training_example_with_gpt4o(task_description: str, example_input: str) -> dict:
'''Use GPT-4o to generate a training example for a smaller model.'''
prompt = f'''You are creating a training example for fine-tuning a smaller model.
Task: {task_description}
Given this input:
{example_input}
Write the ideal assistant response that demonstrates the correct behavior for this task.
Be specific, accurate, and follow the expected format precisely.'''
response = client.chat.completions.create(
model='gpt-4o', # teacher model
messages=[{'role': 'user', 'content': prompt}]
)
return {
'messages': [
{'role': 'system', 'content': task_description},
{'role': 'user', 'content': example_input},
{'role': 'assistant', 'content': response.choices[0].message.content}
]
}การกรองและตรวจสอบคุณภาพ
ตัวอย่างฝึกทุกตัวอย่างควรผ่านขั้นตอนตรวจสอบคุณภาพก่อนนำเข้า Validate: คำตอบอยู่ในรูปแบบที่ถูกต้อง คำตอบมีความถูกต้อง (สำหรับงานด้านข้อเท็จจริง) คำตอบไม่มีข้อมูลที่แต่งขึ้นหรือเนื้อหาที่เป็นอันตราย คู่คำสั่งกับคำตอบมีความสอดคล้องกัน และตัวอย่างเป็นตัวแทนของกรณีใช้งานจริง ใช้การตรวจสอบอัตโนมัติสำหรับตรวจสอบรูปแบบ และใช้ LLM เป็นผู้ตัดสินด้านคุณภาพเนื้อหา พร้อมให้มนุษย์ตรวจทานตัวอย่างบางส่วน
import json
def validate_training_example(example: dict, schema_validator=None) -> dict:
issues = []
# Format check
if 'messages' not in example:
issues.append('Missing messages field')
return {'valid': False, 'issues': issues}
messages = example['messages']
if not any(m['role'] == 'assistant' for m in messages):
issues.append('No assistant message found')
# Check assistant message quality
assistant_content = next((m['content'] for m in messages if m['role'] == 'assistant'), '')
if len(assistant_content) < 5:
issues.append('Assistant response too short')
# Schema validation for JSON output tasks
if schema_validator:
try:
parsed = json.loads(assistant_content)
schema_validator(parsed) # raises if invalid
except json.JSONDecodeError:
issues.append('Assistant response is not valid JSON')
except Exception as e:
issues.append(f'Schema validation failed: {str(e)}')
return {'valid': len(issues) == 0, 'issues': issues}
# Run validation on all examples before training
examples = load_training_examples('raw_dataset.jsonl')
valid_examples = [e for e in examples if validate_training_example(e)['valid']]
print(f'Valid examples: {len(valid_examples)}/{len(examples)}')การลบข้อมูลซ้ำ
ตัวอย่างที่ซ้ำกันหรือเกือบซ้ำกันในข้อมูลฝึกเป็นสิ่งที่ก่อให้เกิดผลเสีย ตัวอย่างเหล่านี้ทำให้โมเดลปรับเข้ากับตัวอย่างเฉพาะเหล่านั้นมากเกินไป และทำให้ความสามารถในการฝึกเพื่อเรียนรู้รูปแบบที่หลากหลายสูญเปล่า ให้ดำเนินการลบข้อมูลซ้ำก่อนสรุปชุดข้อมูลของคุณ การลบข้อมูลซ้ำแบบตรงกันทุกประการ ใช้การแฮชเพื่อค้นหาตัวอย่างที่เหมือนกัน การลบข้อมูลที่เกือบซ้ำกัน ใช้ MinHash หรือความคล้ายคลึงของเวกเตอร์ฝังตัวเพื่อค้นหาตัวอย่างที่แตกต่างกันเพียงเล็กน้อยในรายละเอียดที่ไม่สำคัญ
import hashlib
from datasketch import MinHash, MinHashLSH
def exact_deduplicate(examples: list[dict]) -> list[dict]:
seen_hashes = set()
unique = []
for ex in examples:
# Hash the user and assistant messages
content = str(ex['messages'])
h = hashlib.md5(content.encode()).hexdigest()
if h not in seen_hashes:
seen_hashes.add(h)
unique.append(ex)
print(f'Exact dedup: {len(examples)} -> {len(unique)} ({len(examples)-len(unique)} removed)')
return unique
def near_deduplicate_by_input(examples: list[dict], similarity_threshold=0.85) -> list[dict]:
# Build index of input texts
inputs = [next((m['content'] for m in ex['messages'] if m['role'] == 'user'), '') for ex in examples]
lsh = MinHashLSH(threshold=similarity_threshold, num_perm=128)
unique_indices = set()
for i, text in enumerate(inputs):
m = MinHash(num_perm=128)
for word in text.lower().split():
m.update(word.encode('utf-8'))
if not lsh.query(m): # no similar items found
lsh.insert(str(i), m)
unique_indices.add(i)
return [examples[i] for i in sorted(unique_indices)]การแบ่งข้อมูลฝึก/ตรวจสอบ
แบ่งชุดข้อมูลของคุณเป็น ชุดฝึกและชุดตรวจสอบ ก่อนเริ่มการปรับแต่งแบบละเอียดแต่ละครั้ง ชุดตรวจสอบใช้เพื่อติดตามการปรับเข้ากับข้อมูลมากเกินไประหว่างการฝึก (หากการสูญเสียของชุดตรวจสอบเพิ่มขึ้นในขณะที่การสูญเสียของชุดฝึกลดลง แสดงว่าโมเดลกำลังปรับเข้ากับข้อมูลมากเกินไป) การแบ่งทั่วไปคือ ข้อมูลฝึก 90% / ข้อมูลตรวจสอบ 10% ตรวจสอบให้แน่ใจว่าการแบ่งเป็นแบบสุ่มและแบ่งตามสัดส่วน หากชุดข้อมูลของคุณมีหมวดหมู่ที่มีความหมาย (เช่น แต่ละชุดมีประเภทเจตนาทั้งหมดในสัดส่วนเท่ากัน)
import random
import json
def split_dataset(examples: list[dict], val_fraction=0.1, seed=42) -> tuple[list, list]:
random.seed(seed) # reproducible split
shuffled = examples.copy()
random.shuffle(shuffled)
n_val = max(1, int(len(shuffled) * val_fraction))
val_set = shuffled[:n_val]
train_set = shuffled[n_val:]
print(f'Train: {len(train_set)} examples, Validation: {len(val_set)} examples')
return train_set, val_set
def save_jsonl(examples: list[dict], path: str):
with open(path, 'w') as f:
for ex in examples:
f.write(json.dumps(ex) + '\n')
# Split and save
examples = load_training_examples('clean_dataset.jsonl')
train, val = split_dataset(examples, val_fraction=0.1)
save_jsonl(train, 'train.jsonl')
save_jsonl(val, 'validation.jsonl')
print(f'Saved train.jsonl ({len(train)}) and validation.jsonl ({len(val)})')การปรับสมดุลชุดข้อมูล
ชุดข้อมูลที่ไม่สมดุลทำให้โมเดลที่ปรับแต่งแบบละเอียดมุ่งเน้นกรณีที่พบบ่อยมากเกินไป และล้มเหลวกับกรณีที่พบได้น้อยแต่สำคัญ หากชุดข้อมูลของคุณมีตัวอย่างหมวดหมู่ A 900 รายการ และหมวดหมู่ B 100 รายการ โมเดลอาจเรียนรู้ให้ทำนาย A เสมอ ปรับสมดุลชุดข้อมูลโดย: เพิ่มตัวอย่างหมวดหมู่ส่วนน้อย (ทำซ้ำตัวอย่างที่พบได้น้อย), ลดตัวอย่างหมวดหมู่ส่วนใหญ่ หรือ สร้างตัวอย่างสังเคราะห์ สำหรับกรณีที่มีตัวแทนน้อย โดยใช้ GPT-4o
from collections import Counter
import random
def analyze_distribution(examples: list[dict], category_extractor) -> dict:
categories = [category_extractor(ex) for ex in examples]
counts = Counter(categories)
print('Category distribution:')
for cat, count in counts.most_common():
print(f' {cat}: {count} ({100*count/len(examples):.1f}%)')
return counts
def oversample_minority(examples: list[dict], category_extractor, target_count: int) -> list[dict]:
by_category = {}
for ex in examples:
cat = category_extractor(ex)
by_category.setdefault(cat, []).append(ex)
balanced = []
for cat, cat_examples in by_category.items():
if len(cat_examples) < target_count:
# Oversample with replacement
oversampled = random.choices(cat_examples, k=target_count)
balanced.extend(oversampled)
else:
# Undersample to target_count
balanced.extend(random.sample(cat_examples, target_count))
random.shuffle(balanced)
return balancedการทำความสะอาดและการปรับข้อมูลให้เป็นมาตรฐาน
ข้อมูลฝึกมักมีความไม่สอดคล้องกันซึ่งส่งผลเสียต่อการปรับแต่งแบบละเอียด เช่น การใช้อักษรตัวพิมพ์ใหญ่และเล็กปะปนกันในช่องข้อมูลขาออก ช่องว่างท้ายข้อความ การใช้เครื่องหมายอัญประกาศไม่สม่ำเสมอ รูปแบบตัวเลขที่ปะปนกัน หรือหลักเกณฑ์การตั้งชื่อคีย์ JSON ที่แตกต่างกัน ปรับข้อมูลเหล่านี้ให้เป็นมาตรฐานก่อนการฝึก โมเดลที่ผ่านการปรับแต่งแบบละเอียดจะเรียนรู้รูปแบบที่ปรากฏในข้อมูลของคุณอย่างตรงตามนั้น — หากข้อมูลของคุณไม่สอดคล้องกัน โมเดลก็จะทำซ้ำความไม่สอดคล้องเหล่านั้น
import json
import re
def normalize_json_output_example(example: dict) -> dict:
'''Normalize JSON output in assistant messages for consistency.'''
messages = example.get('messages', [])
normalized = []
for msg in messages:
if msg['role'] == 'assistant':
content = msg['content'].strip()
# Try to parse and re-serialize JSON for consistent formatting
try:
parsed = json.loads(content)
# Normalize: sort keys, consistent spacing
content = json.dumps(parsed, ensure_ascii=False, sort_keys=True)
except json.JSONDecodeError:
pass # Not JSON output - leave as is
normalized.append({'role': 'assistant', 'content': content})
else:
normalized.append(msg)
return {'messages': normalized}
def normalize_dataset(examples: list[dict]) -> list[dict]:
return [normalize_json_output_example(ex) for ex in examples]การวัดตัวชี้วัดคุณภาพชุดข้อมูล
ก่อนส่งข้อมูลเพื่อการปรับแต่งแบบละเอียด ให้คำนวณ ตัวชี้วัดคุณภาพ ของชุดข้อมูลโดยรวม ตรวจสอบ: จำนวนโทเค็นเฉลี่ยและสูงสุดต่อตัวอย่าง (ตัวอย่างที่ยาวมีต้นทุนการฝึกสูงกว่าและอาจถูกตัดทอน), ความครอบคลุมของคลังคำศัพท์ (ชุดข้อมูลครอบคลุมความหลากหลายทั้งหมดของข้อมูลขาเข้าจากการใช้งานจริงหรือไม่) และคะแนนความสอดคล้อง (ข้อมูลขาเข้าที่คล้ายกันให้ข้อมูลขาออกที่คล้ายกันหรือไม่) ผู้ให้บริการการปรับแต่งแบบละเอียดส่วนใหญ่มีจุดเชื่อมต่อสำหรับตรวจสอบข้อมูล ซึ่งจะตรวจสอบข้อผิดพลาดด้านรูปแบบก่อนเรียกเก็บเงินจากคุณสำหรับการฝึกที่ล้มเหลว
import tiktoken
def analyze_dataset_quality(examples: list[dict], model='gpt-4o-mini') -> dict:
encoder = tiktoken.encoding_for_model(model)
token_counts = []
for ex in examples:
total_tokens = sum(
len(encoder.encode(m['content']))
for m in ex['messages']
)
token_counts.append(total_tokens)
report = {
'total_examples': len(examples),
'avg_tokens_per_example': sum(token_counts) / len(token_counts),
'max_tokens': max(token_counts),
'min_tokens': min(token_counts),
'examples_over_4k_tokens': sum(1 for t in token_counts if t > 4096),
'estimated_training_tokens': sum(token_counts),
'estimated_cost': sum(token_counts) / 1_000_000 * 8.0 # ~$8/1M tokens for gpt-4o-mini
}
for key, value in report.items():
print(f'{key}: {value}')
return reportการปรับปรุงชุดข้อมูลแบบวนซ้ำ
การเตรียมชุดข้อมูลเป็นกระบวนการแบบวนซ้ำ ปรับแต่งโมเดลขนาดเล็กด้วยชุดข้อมูลเริ่มต้นของคุณ ประเมินโมเดลด้วยตัวอย่างที่กันไว้ออกจากการฝึก ระบุรูปแบบความล้มเหลว และติดตามย้อนกลับไปยังช่องว่างหรือปัญหาคุณภาพของชุดข้อมูล จากนั้นแก้ไขข้อมูลและฝึกใหม่ วงจร การปรับปรุงข้อมูลโดยขับเคลื่อนด้วยข้อผิดพลาด นี้เป็นแนวปฏิบัติมาตรฐานในการปรับแต่งแบบละเอียดสำหรับระบบที่ใช้งานจริง และมีประสิทธิภาพมากกว่าการพยายามรวบรวมชุดข้อมูลที่สมบูรณ์แบบให้ได้ภายในการดำเนินการครั้งเดียวอย่างมาก
ความสอดคล้องของพรอมป์ระบบระหว่างตัวอย่าง
หากโมเดลที่ปรับแต่งละเอียดแล้วของคุณจะใช้พรอมต์ระบบเดียวกันเสมอในระบบใช้งานจริง ให้ใส่พรอมต์ระบบนั้นแบบตรงตามต้นฉบับในตัวอย่างการฝึกทุกตัวอย่าง หากต้องการให้โมเดลทำงานได้โดยไม่มีพรอมต์ระบบ ให้ฝึกโดยไม่ใช้พรอมต์ระบบ ความไม่สอดคล้องกันระหว่างเงื่อนไขการฝึกกับเงื่อนไขการอนุมานเป็นสาเหตุสำคัญที่ทำให้การปรับแต่งละเอียดไม่เป็นไปตามความคาดหวัง โมเดลจะเรียนรู้พฤติกรรมที่ขึ้นอยู่กับโครงสร้างพรอมต์แบบตรงตามที่พบระหว่างการฝึก
ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจเกี่ยวกับการเตรียมชุดข้อมูลฝึกสำหรับการปรับแต่งละเอียดจากบทเรียนนี้
ทบทวนบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า คุณภาพของข้อมูลสำคัญกว่าปริมาณข้อมูล ในการปรับแต่งละเอียด ตัวอย่างคุณภาพเยี่ยม 100 ตัวอย่างให้ผลดีกว่าตัวอย่างคุณภาพปานกลาง 10,000 ตัวอย่าง การกำจัดข้อมูลซ้ำ การตรวจสอบความถูกต้อง การสร้างสมดุล และการปรับข้อมูลให้เป็นมาตรฐาน คือขั้นตอนสำคัญ 4 ขั้นตอนในการทำความสะอาดข้อมูลก่อนเริ่มการฝึกทุกครั้ง และ การแบ่งข้อมูลฝึก/ตรวจสอบความถูกต้อง เป็นสิ่งจำเป็นสำหรับตรวจจับการเรียนรู้เกินพอดีระหว่างการฝึก ก่อนที่ประสิทธิภาพในการใช้งานจริงจะลดลง ต่อไปเราจะทำการปรับแต่งละเอียดด้วย LoRA โดยใช้ Hugging Face PEFT
คำถามที่พบบ่อย
บทเรียน “การเตรียมชุดข้อมูลฝึกคุณภาพสูง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การเตรียมชุดข้อมูลฝึกคุณภาพสูง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การเตรียมชุดข้อมูลฝึกคุณภาพสูง”
รวบรวม ทำความสะอาด และจัดรูปแบบข้อมูลที่ทำตามคำสั่งได้ในรูปแบบ Alpaca และ ShareGPT กำจัดข้อมูลซ้ำ และแบ่งเป็นชุดฝึกกับชุดตรวจสอบ คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การเตรียมชุดข้อมูลฝึกคุณภาพสูง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม
ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- เมื่อการปรับแต่งละเอียดดีกว่าการเขียนพรอมต์
- การเตรียมชุดข้อมูลฝึกคุณภาพสูง
- การปรับแต่งละเอียด LoRA ด้วย Hugging Face PEFT
- การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน