Hướng dẫn Fine-Tune LLM: Từ Lý Thuyết Đến Triển Khai Thực Tế

20 tháng 8, 2026·15 phút đọc

Bài viết là cẩm nang chi tiết về fine-tuning LLM, từ việc xác định khi nào cần fine-tune thay vì dùng RAG, đến hiểu sâu toán học đằng sau LoRA/QLoRA và cách triển khai kỹ thuật với mã nguồn cụ thể. Tác giả chia sẻ ca thực tế: fine-tune Mistral 7B giúp tăng độ chính xác từ 35% lên 98% cho tác vụ tạo báo cáo ung thư vú, đồng thời tiết kiệm 320.000 USD chi phí API.

Hướng dẫn Fine-Tune LLM: Từ Lý Thuyết Đến Triển Khai Thực Tế

Hướng dẫn Fine-Tune LLM: Từ Lý Thuyết Đến Triển Khai Thực Tế

Fine-tuning không còn là khái niệm xa vời khi bạn hiểu rõ khi nào cần dùng nó, cách hoạt động của LoRA/QLoRA và quy trình triển khai cụ thể. Bài viết này cung cấp lộ trình từ A-Z với ví dụ thực tế: fine-tune model 7B đạt độ chính xác 98% cho tác vụ y tế phức tạp, vượt xa cả model frontier với chi phí gần như bằng không.

Vì Sao Cần Fine-Tune?

Hãy bắt đầu bằng một ví dụ thực tế. Chúng tôi đã fine-tune một model 7B tham số và kết quả vượt trội hoàn toàn so với các foundation model, nhưng chỉ cho một tác vụ rất hẹp: điền mẫu báo cáo synoptic cho ung thư vú.

Đây là tác vụ cực khó với định dạng đầu vào phức tạp, logic phân nhánh đa tầng và các trường phải xuất hiện theo thứ tự nghiêm ngặt. LLM cần xác định chính xác subtype nào trong 40 loại mô học khác nhau sẽ kích hoạt nhánh trường nào, không được phép hallucination. Một trường sai là toàn bộ đầu ra bị vô hiệu.

Khi dùng system prompts mạnh kết hợp RAG nhẹ, độ chính xác với Claude Opus 4.6 chỉ đạt ~35%. Chúng tôi phải đưa toàn bộ template vào context cùng hướng dẫn chi tiết, khoảng 30.000 token mỗi lần gọi. Kết quả: trường bị thiếu, mục thừa, hallucination — con người phải đọc và sửa lại toàn bộ. Không thể chấp nhận.

Sau khi fine-tune Mistral 7B với QLoRA, độ chính xác nhảy lên ~98%. Tôi thực sự bất ngờ về hiệu quả này.

Phương phápĐộ chính xác
Prompt + RAG35%
QLoRA98%

Chúng tôi cải thiện 63 điểm phần trăm và loại bỏ hoàn toàn chi phí API cho tác vụ này. Ước tính ban đầu nếu chạy với model frontier ở quy mô cần thiết là ~320.000 USD. Giờ thì miễn phí (chưa tính chip fine-tuning và chạy local model).

Đó chính là lý do bạn cần fine-tune.

Khi Nào Nên Fine-Tune?

Hãy tìm một trong các dấu hiệu sau:

Yêu Cầu Định Dạng Khắt Khe, Phức Tạp

Bạn cần LLM xuất ra định dạng cụ thể mà chỉ cần một lỗi nhỏ là hỏng toàn bộ. Ví dụ:

  • Tài liệu doanh nghiệp kế thừa: template độc quyền với vô số nhánh điều kiện
  • Tài liệu pháp lý/tòa án: mỗi khu vực có định dạng riêng, không có trong dữ liệu huấn luyện của LLM
  • Biểu mẫu y tế: phức tạp, nhiều trùng lặp, cần chính xác tuyệt đối

Ràng Buộc Chi Phí

Nếu system prompt dài 10.000-30.000 token chạy trên mỗi API call với hàng nghìn request mỗi ngày, chi phí và độ trễ sẽ tăng vọt. Fine-tuned model đã nội hóa các pattern này, không cần prompt dài.

Logic Phức Tạp và Bùng Nổ Tổ Hợp

System prompts hoạt động tốt với ràng buộc đơn giản, nhưng thất bại khi quy tắc chồng chéo. Nếu tác vụ có cây quyết định khổng lồ ("Nếu A thì B, nhưng nếu C và A thì D, trừ khi E xuất hiện..."), in-context learning sẽ bị giới hạn.

Thêm vào đó, context dài sẽ làm giảm chất lượng. System prompt với 50 quy tắc gần như chắc chắn sẽ bỏ sót vài quy tắc, làm hỏng toàn bộ output.

Phong Cách Riêng (Brand Voice)

Nếu cần giọng văn thương hiệu cụ thể cho chatbot chăm sóc khách hàng, fine-tuning thường hiệu quả hơn system prompts. Prompt 2.000 token cho mỗi tương tác sẽ tốn kém về lâu dài.

Khi Nào Dùng RAG?

Quy tắc chung: RAG bổ sung kiến thức, fine-tuning thay đổi hành vi đầu ra. Chọn RAG nếu:

  • Kiến thức thay đổi thường xuyên (văn bản, chính sách, thông tin cập nhật liên tục)
  • Chỉ cần augment hành vi thỉnh thoảng
  • Chỉ có vài trăm cặp dữ liệu huấn luyện chất lượng
  • Có thể điều chỉnh hành vi bằng system prompt nhỏ

Trong thực tế, giải pháp tốt thường là kết hợp cả hai. Chúng tôi không loại bỏ hoàn toàn system prompts hay RAG, chỉ giảm sự phụ thuộc đáng kể.

Toán Học Đằng Sau LoRA/QLoRA

Hiểu toán học giúp bạn không chỉ copy-paste script mà còn biết cách debug khi gặp lỗi. Ví dụ: không hiểu "rank" là gì sẽ khó chẩn đoán overfitting. Tại sao chọn rank 8 thay vì 32? Giảm alpha sẽ ảnh hưởng gì đến residual stream?

Fine-Tuning Là Gì?

Fine-tuning là sự tiếp nối của quá trình pretraining. Trong pretraining, mục tiêu là dự đoán token tiếp theo. Trong supervised fine-tuning (SFT), mục tiêu tương tự nhưng áp dụng cho các cặp (prompt, completion) cụ thể.

LoRA: Giảm Chiều Hiệu Quả

LoRA dựa trên giả thuyết rằng sự thay đổi trọng số trong fine-tuning có chiều nội tại thấp (intrinsic dimension). Thay vì cập nhật toàn bộ ma trận trọng số W, LoRA chỉ học một ma trận nhỏ ΔW = BA với B và A có rank nhỏ.

Với model 7B, chỉ cần tối ưu ~0,1% tham số mà vẫn đạt chất lượng tương đương full fine-tuning. LoRA tách biệt trọng số đóng băng W0 và adapter ΔW, giúp dễ dàng thử nghiệm, lưu trữ và chuyển đổi giữa các tác vụ.

QLoRA: Tối Ưu Hóa Bộ Nhớ

QLoRA kết hợp LoRA với 3 kỹ thuật chính:

1. 4-bit NormalFloat (NF4)

Thay vì dùng đều các khoảng lượng tử 4-bit, NF4 dựa trên phân phối chuẩn (Gaussian) của trọng số mạng nơ-ron để đặt nhiều điểm lượng tử hơn gần giá trị 0. Kết quả: tái tạo trọng số chính xác hơn với cùng số bit.

2. Double Quantization

Chia trọng số thành các block 64, mỗi block có scaling factor FP32 riêng. Sau đó nhóm 256 scaling factor lại và lượng tử xuống FP8. Tiết kiệm ~0,373 bit mỗi tham số, tương đương 2-3GB VRAM cho model lớn.

3. Paged Optimizers

Tận dụng NVIDIA unified memory để xử lý các spike bộ nhớ không mong muốn trong forward/backward pass, tránh lỗi OOM.

LoRA giúp fine-tuning tiết kiệm bộ nhớ. QLoRA giúp LoRA tiết kiệm hơn nữa.

Tại Sao Chọn QLoRA Thay Vì Full Fine-Tuning?

Model 7B của chúng tôi hoàn toàn có thể full fine-tune, nhưng lợi ích mang lại không đáng kể so với chi phí bộ nhớ và tính toán. LoRA cho phép thử nghiệm adapter độc lập với base model — một lợi thế lớn. QLoRA trở thành lựa chọn hiển nhiên vì vừa tiết kiệm vừa linh hoạt.

Triển Khai Kỹ Thuật

Nếu giống chúng tôi, bạn sẽ dành:

  • 70% thời gian để tạo dữ liệu huấn luyện chất lượng
  • 20% thời gian chạy đánh giá
  • 10% thời gian thực sự chạy fine-tune

Script fine-tuning thực ra rất nhẹ và dễ hiểu. Đừng ngại tự xây dựng pipeline riêng — bạn sẽ tốn nhiều thời gian hơn khi cố tùy biến template có sẵn của người khác.

Tạo Dữ Liệu Huấn Luyện Chất Lượng

Trường hợp lý tưởng: Bạn có 4.000-10.000+ cặp input/output thực tế. Fine-tuning phát huy tối đa khi bạn muốn định hình LLM trả lời theo cách cụ thể.

Trường hợp của chúng tôi: Chỉ có output (báo cáo hoàn chỉnh), không có input (ghi chú tự do của bác sĩ). Giải pháp: dùng kỹ thuật Instruction Backtranslation từ bài báo "Self-Alignment with Instruction Backtranslation" của Li et al. Thay vì "cho input, tạo output", đảo ngược thành "cho output, tạo input".

Quy trình:

  1. Thu thập 10.000 báo cáo synoptic thực tế
  2. Dùng model frontier tạo 4 bản ghi chú giải phẫu bệnh không cấu trúc cho mỗi output (với 4 system prompts khác nhau)
  3. Lọc các cặp dữ liệu dựa trên đánh giá lỗi ban đầu — ưu tiên dữ liệu mà foundation model thất bại
  4. Dùng (input tổng hợp, output thực) làm tập huấn luyện

Tạo nhiều input cho mỗi output giúp model học tính đa dạng — cùng một output có thể đến từ nhiều input khác nhau, tránh hallucination khi có biến thể nhỏ.

Chi Tiết Hyperparameters

Sau đây là các hyperparameter quan trọng nhất, tổng hợp từ nghiên cứu của Unsloth và Thinking Machines Lab:

HyperparameterÝ nghĩaGiá trị đề xuất
Learning RateKích thước bước cập nhậtMặc định 2e-4, sweep: [5e-5, 1e-4, 2e-4, 4e-4, 8e-4]
LoRA Rank (r)Dung lượng adapterMặc định 16, sweep: [8, 16, 32, 64, 128]
LoRA AlphaTỷ lệ scale adapter (α/r)Mặc định 2×r
Batch Size hiệu dụngbatch_size × grad_accumMặc định 16
Số epochsSố lần duyệt tập huấn luyện1-3 epochs
LoRA DropoutRegularizationMặc định 0, sweep nếu overfit: [0, 0.05, 0.1]
Weight DecayPhạt độ lớn trọng số0.01
LR SchedulerHình dạng đường cong LRLinear hoặc cosine, warmup 5-10%

Điểm quan trọng từ nghiên cứu Thinking Machines Lab: Trong paper gốc LoRA, tác giả chỉ áp dụng LoRA cho attention matrices. Nhưng Schulman chứng minh rằng áp dụng LoRA cho tất cả weight matrices (bao gồm MLP và MoE layers) cho kết quả tốt hơn, ngay cả khi giữ nguyên số tham số huấn luyện bằng cách tăng rank cho attention-only.

Script Huấn Luyện Hoàn Chỉnh

Dưới đây là script PyTorch đầy đủ đã được kiểm tra và giản lược từ dự án thực tế:

pip install torch transformers peft trl bitsandbytes datasets accelerate
"""
QLoRA fine-tuning cho Mistral-7B-Instruct.
Các hyperparameter và giá trị mặc định:
Learning Rate        2e-4
LoRA Rank (r)        16
LoRA Alpha           2*r
Effective Batch Size 16 (batch_size * grad_accum_steps)
Epochs               3
...
"""
import argparse
import os
import torch
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    BitsAndBytesConfig,
    EarlyStoppingCallback,
    TrainerCallback,
)
from peft import LoraConfig, PeftModel, get_peft_model, prepare_model_for_kbit_training
from trl import SFTTrainer, SFTConfig, DataCollatorForCompletionOnlyLM
from datasets import load_dataset

BASE_MODEL = "mistralai/Mistral-7B-Instruct-v0.3"
DATA_FILE = ""  # Thêm file JSON dữ liệu của bạn!
RESPONSE_TEMPLATE = "[/INST]"
OUTPUT_ROOT = "./mistral-lora"
SYSTEM_PROMPT = ""  # Thêm system prompt của bạn

class PrintLossCallback(TrainerCallback):
    def on_log(self, args, state, control, logs=None, **kwargs):
        if logs:
            if "loss" in logs:
                print(f"Step {state.global_step} | Train Loss: {logs['loss']:.4f}")
            if "eval_loss" in logs:
                print(f"Step {state.global_step} | Eval Loss: {logs['eval_loss']:.4f}")

def build_dataset(tokenizer, data_file=DATA_FILE, eval_fraction=0.1, seed=42):
    dataset = load_dataset("json", data_files=data_file, split="train")
    
    def to_chat_text(example):
        messages = [
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": example["prompt"]},
            {"role": "assistant", "content": example["completion"]},
        ]
        return {"text": tokenizer.apply_chat_template(messages, tokenize=False)}
    
    dataset = dataset.map(to_chat_text)
    split = dataset.train_test_split(test_size=eval_fraction, seed=seed)
    return split["train"], split["test"]

def load_base_model():
    bnb_config = BitsAndBytesConfig(
        load_in_4bit=True,
        bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16,
        bnb_4bit_use_double_quant=True,
    )
    model = AutoModelForCausalLM.from_pretrained(
        BASE_MODEL,
        quantization_config=bnb_config,
        device_map="auto",
    )
    return prepare_model_for_kbit_training(model)

def build_lora_model(rank, alpha, dropout):
    model = load_base_model()
    lora_config = LoraConfig(
        r=rank,
        lora_alpha=alpha,
        target_modules=[
            "q_proj", "k_proj", "v_proj", "o_proj",
            "gate_proj", "up_proj", "down_proj",
        ],
        lora_dropout=dropout,
        bias="none",
        task_type="CAUSAL_LM",
    )
    return get_peft_model(model, lora_config)

def train(hp, train_ds, eval_ds, tokenizer, collator, output_dir):
    model = build_lora_model(
        rank=hp["rank"],
        alpha=hp["lora_alpha"],
        dropout=hp["lora_dropout"],
    )
    model.print_trainable_parameters()
    
    sft_config = SFTConfig(
        output_dir=output_dir,
        per_device_train_batch_size=hp["per_device_train_batch_size"],
        gradient_accumulation_steps=hp["gradient_accumulation_steps"],
        num_train_epochs=hp["epochs"],
        learning_rate=hp["learning_rate"],
        lr_scheduler_type=hp["lr_scheduler_type"],
        warmup_ratio=hp["warmup_ratio"],
        weight_decay=hp["weight_decay"],
        bf16=True,
        gradient_checkpointing=True,
        logging_steps=10,
        eval_strategy="epoch",
        save_strategy="epoch",
        load_best_model_at_end=True,
        metric_for_best_model="eval_loss",
        greater_is_better=False,
        max_seq_length=32768,
        report_to="none",
    )
    
    trainer = SFTTrainer(
        model=model,
        args=sft_config,
        train_dataset=train_ds,
        eval_dataset=eval_ds,
        data_collator=collator,
        callbacks=[
            EarlyStoppingCallback(early_stopping_patience=3),
            PrintLossCallback(),
        ],
    )
    trainer.train()
    metrics = trainer.evaluate()
    return trainer, metrics

def save_adapter(trainer, tokenizer, output_dir):
    trainer.save_model(output_dir)
    tokenizer.save_pretrained(output_dir)

def merge_and_save(base_model_name, adapter_dir, merged_dir):
    print(f"Đang tải base model để merge: {base_model_name}")
    base_model = AutoModelForCausalLM.from_pretrained(
        base_model_name,
        torch_dtype=torch.bfloat16,
        device_map="auto",
    )
    merged_model = PeftModel.from_pretrained(base_model, adapter_dir)
    merged_model = merged_model.merge_and_unload()
    merged_model.save_pretrained(merged_dir, safe_serialization=True)
    tokenizer = AutoTokenizer.from_pretrained(adapter_dir)
    tokenizer.save_pretrained(merged_dir)
    print(f"Model đã merge lưu tại {merged_dir}")

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--data_file", default=DATA_FILE)
    parser.add_argument("--eval_fraction", type=float, default=0.1)
    parser.add_argument("--lr", type=float, default=2e-4)
    parser.add_argument("--rank", type=int, default=16)
    parser.add_argument("--lora_alpha", type=int, default=None)
    parser.add_argument("--batch_size", type=int, default=4)
    parser.add_argument("--grad_accum", type=int, default=4)
    parser.add_argument("--epochs", type=int, default=3)
    parser.add_argument("--dropout", type=float, default=0.0)
    parser.add_argument("--weight_decay", type=float, default=0.01)
    parser.add_argument("--scheduler", choices=["linear", "cosine"], default="cosine")
    parser.add_argument("--warmup_ratio", type=float, default=0.05)
    parser.add_argument("--merge", action="store_true", help="Merge adapter vào base model sau khi training")
    parser.add_argument("--merged_dir", default=None, help="Thư mục output cho model merged")
    args = parser.parse_args()
    
    os.makedirs(OUTPUT_ROOT, exist_ok=True)
    lora_alpha = args.lora_alpha if args.lora_alpha is not None else 2 * args.rank
    
    hp = {
        "learning_rate": args.lr,
        "rank": args.rank,
        "lora_alpha": lora_alpha,
        "per_device_train_batch_size": args.batch_size,
        "gradient_accumulation_steps": args.grad_accum,
        "epochs": args.epochs,
        "lora_dropout": args.dropout,
        "weight_decay": args.weight_decay,
        "lr_scheduler_type": args.scheduler,
        "warmup_ratio": args.warmup_ratio,
    }
    print("Hyperparameters:", hp)
    
    tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
    tokenizer.pad_token = tokenizer.eos_token
    train_ds, eval_ds = build_dataset(
        tokenizer, data_file=args.data_file, eval_fraction=args.eval_fraction
    )
    collator = DataCollatorForCompletionOnlyLM(
        response_template=RESPONSE_TEMPLATE, tokenizer=tokenizer
    )
    
    trainer, metrics = train(
        hp, train_ds, eval_ds, tokenizer, collator,
        output_dir=os.path.join(OUTPUT_ROOT, "run"),
    )
    print("Final eval metrics:", metrics)
    
    adapter_dir = os.path.join(OUTPUT_ROOT, "final")
    save_adapter(trainer, tokenizer, adapter_dir)
    
    if args.merge:
        merged_dir = args.merged_dir or os.path.join(OUTPUT_ROOT, "merged")
        merge_and_save(BASE_MODEL, adapter_dir, merged_dir)

if __name__ == "__main__":
    main()

Giải Thích Các Thành Phần Chính

Phần 1: Nạp dữ liệu — Script load file JSON với các trường "prompt" và "completion", chuyển thành định dạng chat template, rồi tách train/test với tỷ lệ 90/10.

Phần 2: Xây dựng model — BitsAndBytes xử lý lượng tử hóa 4-bit. Lưu ý: target_modules bao gồm tất cả các lớp (q_proj, k_proj, v_proj, o_proj, gate_proj, up_proj, down_proj) theo khuyến nghị từ nghiên cứu Thinking Machines Lab. Điều này hoạt động hiệu quả trong thực tế!

Phần 3: Training loop — Một số điểm quan trọng trong SFTConfig:

  • bf16=True + gradient_checkpointing=True: Giảm bộ nhớ đáng kể trong forward/backward pass
  • load_best_model_at_end=True + metric_for_best_model="eval_loss": Tự động chọn checkpoint tốt nhất thay vì giữ epoch cuối (có thể đã overfit)
  • max_seq_length=32768: Giới hạn độ dài chuỗi cho các ghi chú bệnh lý dài

Phần 4: Lưu và merge adapter — Sau training, bạn có LoRA adapter vài trăm MB. Để triển khai production, merge adapter vào base model giúp loại bỏ phép nhân ma trận phụ khi serve và tương thích với mọi inference stack chuẩn.

Đánh Giá Với Custom Harness

Chúng tôi xây dựng bộ đánh giá riêng cho tác vụ báo cáo synoptic. Vì cấu trúc template xác định trước trường nào bắt buộc cho từng subtype, chúng tôi mã hóa schema và kiểm tra theo 4 tiêu chí:

  • Recall: Có đủ tất cả trường bắt buộc cho nhánh đúng?
  • Precision: Có trường nào bị hallucination không thuộc nhánh đó?
  • Thứ tự: Các trường có xuất hiện đúng thứ tự không?
  • Độ chính xác giá trị: Giá trị categorical/numeric có khớp không?

Kết Quả Trên Cùng Tập Đánh Giá

MetricFoundation model (RAG + prompt)Fine-tuned Mistral 7B
Độ chính xác tài liệu nghiêm ngặt~35%~98%
Tài liệu ≥1 trường hallucinated~41%~2%
Tài liệu ≥1 trường bị thiếu~52%~3%
Tài liệu vi phạm thứ tự~23%<1%
Độ chính xác cấp trường~71%~99,4%

Harness đã biến "cảm giác tốt hơn" thành con số có thể bảo vệ trước ban lãnh đạo.

Bài Học Kinh Nghiệm

Loss ≠ Chất Lượng Đầu Ra

Eval_loss đi ngang không có nghĩa là checkpoint không còn hallucination trên các subtype hiếm. Đừng chọn checkpoint cuối chỉ dựa trên loss.

Oversample Các Nhánh Hiếm

Subtype xuất hiện hiếm trong báo cáo thực tế sẽ bị thiếu đại diện trong split ngẫu nhiên. Hãy tăng trọng số cho chúng, nếu không model sẽ giỏi các case phổ biến nhưng thất bại ở edge cases — chính là nơi con người ít bắt lỗi nhất.

Cẩn Thận Rò Rỉ Dữ Liệu Tổng Hợp

Vì input tổng hợp do LLM tạo, chúng dễ vô tình lặp lại cụm từ từ field headers của template. Điều này khiến model có đường tắt trên dữ liệu tổng hợp nhưng vấp ngã với ghi chú thực tế của bác sĩ. Loại bỏ các cụm từ giống header khỏi generation prompts quan trọng hơn chúng tôi tưởng.

Luôn Giữ Một Phần Đánh Giá Thủ Công

Ngay cả với độ chính xác nghiêm ngặt 98%, chúng tôi vẫn duy trì spot-check thủ công định kỳ do rủi ro cao. Custom eval harness bắt được lỗi cấu trúc, nhưng không thể thay thế chuyên gia domain.

Tổng Kết

Fine-tuning dành cho hành vi cần chính xác, lặp lại và rẻ ở quy mô lớn. Tác vụ của chúng tôi là ví dụ hoàn hảo: định dạng đầu ra cố định, phân nhánh sâu, nơi đúng 90% trên bất kỳ trường nào cũng đồng nghĩa với sai.

Chúng tôi vẫn giữ RAG và system prompts cho các phần pipeline cần kiến thức mới. Chúng tôi chỉ ngừng yêu cầu một system prompt 30.000 token làm công việc của fine-tuning.

Hy vọng bài viết giúp bạn hiểu không chỉ toán học đằng sau LoRA/QLoRA mà còn cách tự triển khai. Hai thư viện Python với hệ sinh thái Hugging Face là tất cả những gì bạn cần — phần còn lại là dữ liệu chất lượng và sự kiên nhẫn.

Chúc bạn thành công!

Tài Liệu Tham Khảo

  1. Aghajanyan et al., Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning, arXiv:2012.13255
  2. Dettmers et al., QLoRA: Efficient Finetuning of Quantized LLMs, arXiv:2305.14314
  3. Hu et al., LoRA: Low-Rank Adaptation of Large Language Models, arXiv:2106.09685
  4. Li et al., Self-Alignment with Instruction Backtranslation, ICLR 2024
  5. Wei et al., Finetuned Language Models are Zero-Shot Learners, arXiv:2109.01652
  6. Schulman / Thinking Machines Lab, LoRA without Regret
  7. Unsloth, LoRA Hyperparameters Guide
  8. BitsAndBytes Foundation, GitHub Repository
  9. Hugging Face, Transformers, PEFT, TRL, Datasets
  10. Mistral AI, Mistral-7B-Instruct-v0.3
Chia sẻ:FacebookX
Nội dung tổng hợp bằng AI, mang tính tham khảo. Xem bài gốc ↗