0Pricing
AI Engineering Academy · บทเรียน

การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน

ทำการประเมินเชิงปริมาณโดยเปรียบเทียบโมเดลพื้นฐานกับโมเดลที่ปรับแต่งละเอียดบนกรณีทดสอบที่กันไว้ แปลงเป็น GGUF เพื่ออนุมานในเครื่อง และให้บริการผ่าน llama.cpp หรือ vLLM

การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน เป็นบทเรียน AI Engineering Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน AI Engineering Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องประเมินก่อนนำไปใช้งาน

โมเดลที่ปรับแต่งละเอียดแล้วซึ่งทำงานได้ดีบนข้อมูลการฝึก อาจทำงานแย่กว่าโมเดลพื้นฐานเมื่อใช้กับกรณีใช้งานจริงของคุณ วิธีเดียวที่จะทราบได้คือการประเมินอย่างเข้มงวด การปรับแต่งละเอียดอาจทำให้เกิด การลืมอย่างรุนแรง (สูญเสียความสามารถที่โมเดลพื้นฐานเคยมี) การปรับให้เฉพาะทางมากเกินไป (ทำงานได้ดีในงานของคุณแต่แย่ลงในงานใกล้เคียง) หรือการถดถอยอย่างละเอียดในพฤติกรรมด้านความปลอดภัย อย่านำโมเดลที่ปรับแต่งละเอียดแล้วไปใช้งานโดยไม่ประเมินเทียบกับโมเดลพื้นฐานด้วยชุดทดสอบที่เป็นตัวแทนของการใช้งานจริง

การสร้างชุดทดสอบที่กันไว้ออกจากการฝึก

ชุดทดสอบของคุณต้องแยกออกจากข้อมูลการฝึกและการตรวจสอบความถูกต้องโดยสมบูรณ์ โดยเป็นตัวอย่างที่โมเดลไม่เคยเห็นในขั้นตอนใดของการฝึก ชุดทดสอบควรแทน การกระจายตัวของอินพุตในการใช้งานจริงทั้งหมด ซึ่งรวมถึงกรณีทั่วไป กรณีขอบ และอินพุตที่ออกแบบมาเพื่อโจมตี สำหรับงานทำตามคำสั่ง ให้รวมตัวอย่างที่ต้องทำตามคำสั่งทุกส่วน ไม่ใช่เฉพาะส่วนที่พบบ่อยที่สุด โดยทั่วไป ชุดทดสอบ 100-500 ตัวอย่างก็เพียงพอสำหรับการประเมินที่น่าเชื่อถือ

import json
from typing import TypedDict

class TestCase(TypedDict):
    input: str                 # the user message
    expected_output: str       # the ideal response
    category: str              # e.g., 'format', 'accuracy', 'edge_case'
    evaluation_method: str     # 'exact_match', 'json_schema', 'llm_judge'

# Load test set (never used during training)
def load_test_set(path: str) -> list[TestCase]:
    cases = []
    with open(path) as f:
        for line in f:
            data = json.loads(line.strip())
            cases.append({
                'input': data['messages'][-2]['content'],  # user message
                'expected_output': data['messages'][-1]['content'],  # assistant response
                'category': data.get('metadata', {}).get('category', 'general'),
                'evaluation_method': data.get('metadata', {}).get('eval_method', 'llm_judge')
            })
    return cases

test_set = load_test_set('test.jsonl')
print(f'Test set loaded: {len(test_set)} examples')

ตัวชี้วัดเชิงปริมาณสำหรับการประเมินเฉพาะงาน

เลือกตัวชี้วัดการประเมินให้ตรงกับงานของคุณ สำหรับ การดึงข้อมูล JSON ให้วัดอัตราการเป็นไปตามโครงสร้างและความถูกต้องในระดับฟิลด์ สำหรับ การจำแนกประเภท ให้วัดความถูกต้อง ความแม่นยำ และการเรียกคืนแยกตามประเภท สำหรับ การสร้างข้อความ ให้ใช้การให้คะแนนโดย LLM ในฐานะผู้ตัดสินเพื่อประเมินคุณภาพ สำหรับ การทำตามรูปแบบ ให้วัดอัตราการเป็นไปตามรูปแบบอย่างตรงตามข้อกำหนด เรียกใช้ตัวชี้วัดแต่ละรายการกับทั้งโมเดลพื้นฐานและโมเดลที่ปรับแต่งละเอียดแล้ว เพื่อวัดส่วนต่างของการปรับปรุง

import json

def evaluate_json_extraction(model_output: str, expected: str, schema: dict) -> dict:
    metrics = {'valid_json': False, 'schema_compliant': False, 'field_accuracy': 0.0}
    
    try:
        parsed = json.loads(model_output.strip())
        metrics['valid_json'] = True
        
        # Check schema compliance
        required_fields = schema.get('required', [])
        all_present = all(field in parsed for field in required_fields)
        correct_types = all(
            isinstance(parsed.get(field), schema['properties'][field]['expected_type'])
            for field in required_fields if field in parsed
        )
        metrics['schema_compliant'] = all_present and correct_types
        
        # Field-level accuracy against expected output
        expected_parsed = json.loads(expected)
        correct_fields = sum(1 for k in expected_parsed if parsed.get(k) == expected_parsed[k])
        metrics['field_accuracy'] = correct_fields / len(expected_parsed) if expected_parsed else 0.0
    
    except json.JSONDecodeError:
        pass  # valid_json stays False
    
    return metrics

การประเมินโดย LLM ในฐานะผู้ตัดสิน

สำหรับงานสร้างข้อความปลายเปิด ให้ใช้ LLM ในฐานะผู้ตัดสินเพื่อให้คะแนนเอาต์พุตของโมเดลที่ปรับแต่งละเอียดแล้ว โดยเทียบกับเอาต์พุตที่คาดหวัง สั่ง GPT-4o ให้ทำหน้าที่เป็นผู้ประเมิน ระบุอินพุต เอาต์พุตที่คาดหวัง และเอาต์พุตของโมเดล แล้วขอให้ให้คะแนนความถูกต้อง ความครบถ้วน และการเป็นไปตามรูปแบบในระดับ 1-5 หาค่าเฉลี่ยคะแนนตลอดชุดทดสอบเพื่อได้คะแนนคุณภาพโดยรวม จากนั้นเปรียบเทียบคะแนนของโมเดลที่ปรับแต่งละเอียดแล้วกับคะแนนของโมเดลพื้นฐานในชุดทดสอบเดียวกัน

from openai import OpenAI

client = OpenAI()

def llm_judge_score(instruction: str, expected: str, actual: str) -> dict:
    judge_prompt = f'''Evaluate the quality of an AI assistant response.

Instruction given to assistant:
{instruction}

Expected ideal response:
{expected}

Actual response from model being evaluated:
{actual}

Rate the actual response on these criteria (1=poor, 5=excellent):
1. Correctness: Is the information accurate?
2. Format compliance: Does it follow the expected output format?
3. Completeness: Does it address all parts of the instruction?

Return JSON: {{"correctness": N, "format": N, "completeness": N, "overall": N, "reason": "brief explanation"}}'''
    
    response = client.chat.completions.create(
        model='gpt-4o',
        messages=[{'role': 'user', 'content': judge_prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(response.choices[0].message.content)

การเรียกใช้การประเมินเปรียบเทียบ

ทำการประเมินแบบแข่งขันโดยเปรียบเทียบโมเดลพื้นฐาน โมเดลที่ปรับแต่งละเอียดแล้ว (และอาจรวมแนวทางพื้นฐานที่ใช้พรอมต์อย่างมีประสิทธิภาพ) กับกรณีทดสอบทั้งหมด สร้างเอาต์พุตจากแต่ละโมเดลสำหรับทุกกรณีทดสอบ แล้วให้คะแนนเอาต์พุตทั้งหมดด้วยตัวชี้วัดการประเมิน จัดทำตารางเปรียบเทียบที่แสดงคะแนนตัวชี้วัด ส่วนเบี่ยงเบนมาตรฐาน และตัวอย่างที่โมเดลที่ปรับแต่งละเอียดแล้วทำได้ดีกว่าหรือแย่กว่าแนวทางพื้นฐาน

def run_full_evaluation(test_set: list, models: dict, system_prompt: str) -> dict:
    results = {name: {'scores': [], 'errors': 0} for name in models}
    
    for i, test_case in enumerate(test_set):
        print(f'Evaluating test case {i+1}/{len(test_set)}')
        
        for model_name, model_fn in models.items():
            try:
                output = model_fn(test_case['input'], system_prompt)
                score = llm_judge_score(
                    test_case['input'],
                    test_case['expected_output'],
                    output
                )
                results[model_name]['scores'].append(score['overall'])
            except Exception as e:
                results[model_name]['errors'] += 1
                results[model_name]['scores'].append(0)
    
    # Summarize
    summary = {}
    for name, data in results.items():
        scores = data['scores']
        summary[name] = {
            'mean_score': sum(scores) / len(scores),
            'errors': data['errors']
        }
        print(f'{name}: mean={summary[name]["mean_score"]:.2f}, errors={data["errors"]}')
    return summary

การทดสอบการถดถอยเพื่อจับการลืมอย่างรุนแรง

การปรับแต่งละเอียดอาจทำให้ความสามารถทั่วไปของโมเดลลดลง ซึ่งเป็นปรากฏการณ์ที่เรียกว่า การลืมอย่างรุนแรง ให้เรียกใช้ชุดการทดสอบการถดถอยกับทั้งโมเดลพื้นฐานและโมเดลที่ปรับแต่งละเอียดแล้ว โดยครอบคลุมงานที่คุณให้ความสำคัญนอกเหนือจากงานเป้าหมาย เช่น การตอบคำถามทั่วไป การให้เหตุผล การสร้างโค้ด และการทำตามคำสั่ง หากโมเดลที่ปรับแต่งละเอียดแล้วได้คะแนนในงานเหล่านี้ต่ำลงอย่างมีนัยสำคัญ แรงก์ LoRA ของคุณอาจสูงเกินไป หรือคุณอาจฝึกนานเกินไป

REGRESSION_TEST_CASES = [
    # General QA
    {'input': 'What is the capital of France?', 'expected_substring': 'Paris'},
    {'input': 'What is 17 * 23?', 'expected_substring': '391'},
    # Instruction following
    {'input': 'List 3 planets. Format as: 1. Planet Name', 'expected_pattern': r'^1\. '},
    # Reasoning
    {'input': 'If all A are B and all B are C, are all A also C?', 'expected_substring': 'yes'},
]

def run_regression_tests(model_fn, test_cases: list) -> float:
    passed = 0
    for test in test_cases:
        output = model_fn(test['input'], '')
        if 'expected_substring' in test:
            if test['expected_substring'].lower() in output.lower():
                passed += 1
        elif 'expected_pattern' in test:
            import re
            if re.search(test['expected_pattern'], output):
                passed += 1
    
    rate = passed / len(test_cases)
    print(f'Regression test pass rate: {rate:.1%} ({passed}/{len(test_cases)})')
    return rate

การแปลงเป็น GGUF สำหรับการอนุมานภายในเครื่อง

สำหรับการนำไปใช้งานภายในเครื่องโดยไม่ต้องมีโครงสร้างพื้นฐาน GPU ราคาแพง ให้แปลงโมเดลที่รวมแล้วเป็น รูปแบบ GGUF และเรียกใช้การอนุมานด้วย llama.cpp GGUF รองรับระดับการทำควอนไทซ์หลากหลายระดับ ได้แก่ Q4_K_M (4 บิต สมดุลระหว่างคุณภาพกับความเร็วที่ดี), Q8_0 (8 บิต คุณภาพใกล้เคียงความละเอียดเต็ม) และ Q2_K (2 บิต เร็วมากแต่คุณภาพต่ำกว่า) โมเดล 7B ที่ทำควอนไทซ์แบบ Q4 ต้องใช้ RAM เพียงประมาณ 4GB และสามารถทำงานบน CPU ได้ที่ความเร็ว 1-5 โทเคนต่อวินาที

# Step 1: Convert merged HuggingFace model to GGUF
# git clone https://github.com/ggerganov/llama.cpp
# python llama.cpp/convert_hf_to_gguf.py ./merged-model --outtype f16 --outfile model-f16.gguf

# Step 2: Quantize to 4-bit
# ./llama.cpp/llama-quantize model-f16.gguf model-q4.gguf Q4_K_M

# Step 3: Run inference with llama.cpp Python bindings
# pip install llama-cpp-python
from llama_cpp import Llama

llm = Llama(
    model_path='./model-q4.gguf',
    n_ctx=4096,         # context window
    n_threads=8,        # CPU threads
    n_gpu_layers=0      # set > 0 to offload layers to GPU
)

output = llm.create_chat_completion(
    messages=[{'role': 'user', 'content': 'What is the capital of France?'}],
    temperature=0.1
)
print(output['choices'][0]['message']['content'])

การให้บริการด้วย vLLM สำหรับการใช้งานจริง

สำหรับการให้บริการโมเดลที่ปรับแต่งละเอียดแล้วในระบบใช้งานจริงในระดับขนาดใหญ่ vLLM เป็นมาตรฐานที่ใช้กันในปัจจุบัน vLLM ใช้ PagedAttention เพื่อจัดชุดคำขอหลายรายการเข้าด้วยกันอย่างมีประสิทธิภาพ ทำให้ปริมาณงานของ GPU เพิ่มขึ้นอย่างมาก โดยรองรับจุดปลายทาง API ที่เข้ากันได้กับ OpenAI จึงสามารถใช้แทน API ของ OpenAI ได้ทันที GPU A100 เพียงหนึ่งตัวที่เรียกใช้ vLLM กับโมเดล 7B ที่ปรับแต่งละเอียดแล้ว สามารถรองรับคำขอหลายร้อยรายการต่อนาที

# Start vLLM server (run from command line)
# pip install vllm
# python -m vllm.entrypoints.openai.api_server \
#     --model ./merged-model \
#     --host 0.0.0.0 \
#     --port 8000 \
#     --max-model-len 4096 \
#     --tensor-parallel-size 1

# Use with OpenAI client (drop-in replacement)
from openai import OpenAI

client = OpenAI(
    base_url='http://localhost:8000/v1',
    api_key='not-needed'  # vLLM doesn't require auth by default
)

response = client.chat.completions.create(
    model='merged-model',  # model name matches the path you passed to vLLM
    messages=[{'role': 'user', 'content': 'Extract JSON from: "Alice, 30, NYC"'}]
)
print(response.choices[0].message.content)

การทดสอบ A/B กับโมเดลที่ปรับแต่งละเอียดแล้ว

ก่อนเปลี่ยนไปใช้โมเดลที่ปรับแต่งละเอียดแล้วในระบบใช้งานจริงทั้งหมด ให้ทำ การทดสอบ A/B โดยส่งทราฟฟิกจากการใช้งานจริงบางส่วน (เริ่มที่ 5-10%) ไปยังโมเดลที่ปรับแต่งละเอียดแล้ว ขณะที่ทราฟฟิกส่วนใหญ่ยังใช้โมเดลพื้นฐานหรือแนวทางพรอมต์เดิม ติดตามคะแนนคุณภาพ เวลาแฝง และตัวชี้วัดความพึงพอใจของผู้ใช้ของทั้งสองกลุ่ม เพิ่มสัดส่วนทราฟฟิกของโมเดลที่ปรับแต่งละเอียดแล้วก็ต่อเมื่อการทดสอบ A/B ยืนยันว่ามีการปรับปรุง หลังมีคำขอจำนวนมากพอที่จะให้ผลอย่างมีนัยสำคัญทางสถิติ

import random

class ModelRouter:
    def __init__(self, fine_tuned_traffic_fraction=0.1):
        self.ft_fraction = fine_tuned_traffic_fraction
        self.metrics = {'base': {'count': 0, 'quality_sum': 0}, 'fine_tuned': {'count': 0, 'quality_sum': 0}}

    def route(self, user_id: str, request: str) -> dict:
        # Deterministic routing by user_id (same user always goes to same model)
        use_fine_tuned = (hash(user_id) % 100) < (self.ft_fraction * 100)
        model_group = 'fine_tuned' if use_fine_tuned else 'base'
        
        response = call_model(request, use_fine_tuned=use_fine_tuned)
        return {'response': response, 'model_group': model_group}

    def record_quality(self, model_group: str, quality_score: float):
        self.metrics[model_group]['count'] += 1
        self.metrics[model_group]['quality_sum'] += quality_score

    def ab_test_summary(self) -> dict:
        summary = {}
        for group, data in self.metrics.items():
            avg = data['quality_sum'] / data['count'] if data['count'] > 0 else 0
            summary[group] = {'avg_quality': avg, 'n': data['count']}
        return summary

การดูแลรักษาโมเดลที่ปรับแต่งละเอียดแล้วในระยะยาว

โมเดลที่ปรับแต่งละเอียดแล้วต้องได้รับการดูแลรักษาอย่างต่อเนื่อง เมื่อโมเดลพื้นฐานอัปเดต (เช่น GPT-4o เวอร์ชันใหม่ หรือ Mistral รุ่นใหม่) ค่าน้ำหนักของตัวปรับอาจเข้ากันไม่ได้ และคุณอาจต้องฝึกใหม่ เมื่อข้อกำหนดของงานเปลี่ยนแปลง คุณต้องอัปเดตข้อมูลการฝึกและฝึกใหม่ เมื่อค้นพบรูปแบบความล้มเหลวใหม่ในการใช้งานจริง ให้เพิ่มตัวอย่างลงในชุดข้อมูลฝึก วางแผน การฝึกใหม่เป็นระยะให้เป็นส่วนหนึ่งของเวิร์กโฟลว์การดำเนินงาน ML ในระบบใช้งานจริง

เมทริกซ์การตัดสินใจนำไปใช้งาน

การเลือกกลยุทธ์การนำโมเดลที่ปรับแต่งแล้วไปใช้งานขึ้นอยู่กับขนาดการใช้งานและข้อจำกัดด้านโครงสร้างพื้นฐานของคุณ สำหรับปริมาณการใช้งานต่ำ (น้อยกว่า 1,000 คำขอต่อวัน) API สำหรับการปรับแต่งโมเดลของ OpenAI เป็นตัวเลือกที่ง่ายที่สุด สำหรับปริมาณการใช้งานปานกลาง (1,000–100,000 คำขอต่อวัน) ให้พิจารณาใช้ vLLM บนอินสแตนซ์ GPU เดียว สำหรับแอปพลิเคชันที่มีปริมาณการใช้งานสูงหรือมีข้อกำหนดด้านเวลาแฝงอย่างเข้มงวด ให้ใช้ vLLM กับ GPU หลายตัว พิจารณาการประมวลผลแบบขนานของเทนเซอร์ และเพิ่มชั้นแคชไว้ด้านหน้า สำหรับข้อมูลที่มีความอ่อนไหวด้านความเป็นส่วนตัว ให้โฮสต์ด้วยตนเองบนโครงสร้างพื้นฐานของคุณโดยใช้ GGUF/llama.cpp หรือ vLLM

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจของคุณเกี่ยวกับการประเมินและการนำโมเดลที่ปรับแต่งแล้วไปใช้งานจากบทเรียนนี้

สรุปบทเรียน

ในบทเรียนนี้ คุณได้เรียนรู้ว่า การประเมินก่อนนำไปใช้งานอย่างเคร่งครัด โดยเปรียบเทียบโมเดลที่ปรับแต่งแล้วกับโมเดลพื้นฐานบนกรณีทดสอบที่กันไว้นั้นเป็นสิ่งที่ขาดไม่ได้ การทดสอบการถดถอยช่วยตรวจจับการลืมความสามารถทั่วไปอย่างรุนแรงซึ่งเกิดจากการปรับให้เฉพาะทางมากเกินไป และตัวเลือกในการนำไปใช้งานครอบคลุมตั้งแต่ API การปรับแต่งโมเดลที่ OpenAI ดูแลให้ เพื่อความเรียบง่าย ไปจนถึง vLLM สำหรับให้บริการในสภาพแวดล้อมจริงที่ต้องรองรับปริมาณงานสูง และ GGUF/llama.cpp สำหรับการอนุมานภายในเครื่องด้วย CPU ขอแสดงความยินดีที่เรียนจบเส้นทางวิศวกรรม AI!

คำถามที่พบบ่อย

บทเรียน “การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส AI Engineering Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส AI Engineering Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน”

ทำการประเมินเชิงปริมาณโดยเปรียบเทียบโมเดลพื้นฐานกับโมเดลที่ปรับแต่งละเอียดบนกรณีทดสอบที่กันไว้ แปลงเป็น GGUF เพื่ออนุมานในเครื่อง และให้บริการผ่าน llama.cpp หรือ vLLM คุณปฏิบัติ AI Engineering Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน AI Engineering Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน AI Engineering Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน AI Engineering Academy นี้ได้ไหม

ได้ บทเรียน AI Engineering Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. เมื่อการปรับแต่งละเอียดดีกว่าการเขียนพรอมต์
  2. การเตรียมชุดข้อมูลฝึกคุณภาพสูง
  3. การปรับแต่งละเอียด LoRA ด้วย Hugging Face PEFT
  4. การประเมินและนำโมเดลที่ปรับแต่งละเอียดไปใช้งาน
← กลับไปที่ AI Engineering Academy