Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Unsloth 빠른 튜토리얼

Unsloth는 대규모 언어 모델을 빠르고 효율적으로 미세 조정하기 위한 라이브러리입니다. Hugging Face Transformers 라이브러리를 기반으로 구축되었으며, 다양한 작업에 대해 모델을 파인튜닝하는 데 사용할 수 있습니다. 여기서는 Llama 3.1 모델이 텍스트를 SQL로 변환하는 생성 작업을 수행하도록 학습시키겠습니다.

Unsloth를 사용하면 단일 GPU 환경에서 표준 미세 조정보다 2배 빠르게 학습하고 메모리를 60% 적게 사용할 수 있습니다. Unsloth는 QLoRA(Quantized Low Rank Adaptation)라는 기법을 사용하여 모델을 양자화하고, 모델 전체 대신 소수의 추가 학습 가능 매개변수만 학습합니다. 덕분에 단일 NVIDIA H100 GPU에서 모델을 학습시킬 수 있습니다.

flash-attn과 xformers는 pip를 직접 사용하여 소스에서 설치해야 합니다.

# Install flash-attn
poetry run pip install flash-attn --no-build-isolation

# Install xformers
poetry run pip install -v -U git+https://github.com/facebookresearch/xformers.git@main#egg=xformers

# Install unsloth
poetry run pip install "unsloth[colab-new] @ git+https://github.com/unslothai/unsloth.git"

나머지는 poetry를 통해 PyPI에서 설치할 수 있습니다.

[tool.poetry.dependencies]
trl = "^0.9.6"
nvitop = "^1.3.2"
xformers = "0.0.27"
peft = "^0.12.0"
accelerate = "^0.33.0"
bitsandbytes = "^0.43.3"

이제 train.py 스크립트를 초기화할 수 있습니다. 다음 Hugging Face 라이브러리들을 불러오십시오:

import torch

from datasets import load_dataset
from transformers import EarlyStoppingCallback, TextStreamer, TrainingArguments
from trl import SFTTrainer

from unsloth import FastLanguageModel, is_bfloat16_supported
from unsloth.chat_templates import get_chat_template

4비트로 양자화된 80억 매개변수 Llama 3.1 모델을 다운로드하겠습니다. 이는 모델의 가중치가 16비트 대신 4비트를 사용하도록 압축되었다는 뜻입니다. 이로 인해 모델을 훨씬 빠르게 불러오고 사용할 수 있지만, 여전히 상당히 큰 모델입니다.

max_seq_length = 2048
model, tokenizer = FastLanguageModel.from_pretrained(
    model_name="unsloth/Meta-Llama-3.1-8B-bnb-4bit",
    max_seq_length=max_seq_length,
    load_in_4bit=True,
    dtype=None,
)

model = FastLanguageModel.get_peft_model(
    model,
    r=16,
    lora_alpha=16,
    lora_dropout=0,
    target_modules=[
        "q_proj",
        "k_proj",
        "v_proj",
        "up_proj",
        "down_proj",
        "o_proj",
        "gate_proj",
    ],
    use_rslora=True,
    use_gradient_checkpointing="unsloth",
)

tokenizer = get_chat_template(
    tokenizer,
    chat_template="chatml",
)

텍스트를 SQL로 변환하는 프롬프트로 구성된 합성 데이터셋을 사용하겠습니다.

def convert(question):
    return {"user": question["sql_prompt"], "assistant": question["sql"]}


def apply_template(examples):
    messages = examples["conversations"]
    text = [
        tokenizer.apply_chat_template(
            convert(message), tokenize=False, add_generation_prompt=False
        )
        for message in messages
    ]
    return {"text": text}


dataset = load_dataset("gretelai/synthetic_text_to_sql", split="train")
dataset = dataset.map(apply_template, batched=True)

코사인 어닐링 웜 리스타트(cosine annealing warm restarts) 스케줄러와 함께 8비트 AdamW 옵티마이저를 사용하겠습니다. 또한 과적합을 방지하기 위해 조기 종료(early stopping)를 추가하겠습니다.

callbacks = [
    EarlyStoppingCallback(early_stopping_patience=3),
]

training_args = TrainingArguments(
    learning_rate=3e-4,
    lr_scheduler_type="linear",
    per_device_train_batch_size=8,
    gradient_accumulation_steps=2,
    num_train_epochs=6,
    fp16=not is_bfloat16_supported(),
    bf16=is_bfloat16_supported(),
    logging_steps=1,
    optim = "adamw_8bit",
    lr_scheduler_type = "cosine_with_restarts",
    weight_decay=0.05,
    warmup_steps=10,
    output_dir="output",
    seed=0,
)

trainer = SFTTrainer(
    model=model,
    tokenizer=tokenizer,
    train_dataset=dataset,
    dataset_text_field="text",
    max_seq_length=max_seq_length,
    dataset_num_proc=2,
    packing=True,
    args=training_args,
    load_best_model_at_end=True,
    metric_for_best_model="eval_loss",
    callbacks=callbacks,
)
trainer.train()
print("Done.")

이를 실행하면 다음과 같은 출력을 볼 수 있습니다. 이 작업은 6 에포크 동안 실행되며, Nvidia H100 GPU에서 완료까지 약 2~3시간이 소요됩니다.

# ==((====))==  Unsloth - 2x faster free finetuning | Num GPUs = 1
#    \\   /|    Num examples = 2,254 | Num Epochs = 3
# O^O/ \_/ \    Batch size per device = 2 | Gradient Accumulation steps = 4
# \        /    Total batch size = 8 | Total steps = 843
#  "-____-"     Number of trainable parameters = 29,884,416

이제 모델을 사용하여 텍스트를 생성할 수 있습니다.

model = FastLanguageModel.for_inference(model)

messages = [
    {
        "user": "What is the average salary of employees in the IT department?",
        "assistant": "",
    },
]
inputs = tokenizer.apply_chat_template(
    messages,
    tokenize=True,
    add_generation_prompt=True,
    return_tensors="pt",
).to("cuda")

text_streamer = TextStreamer(tokenizer)
_ = model.generate(
    input_ids=inputs, streamer=text_streamer, max_new_tokens=128, use_cache=True
)

모델은 다양한 형식으로 내보낼 수도 있습니다.

model.save_pretrained_merged("model", tokenizer, save_method="merged_16bit")

trainer_stats = trainer.train()
print("Done.")


model.save_pretrained("lora_model")
tokenizer.save_pretrained("lora_model")

print("Merging model")
model.save_pretrained_merged("fused_model", tokenizer, save_method="merged_16bit")

print("Saving gguf")
model.save_pretrained_gguf("ggufs", tokenizer, quantization_method="f16")
model.save_pretrained_gguf("ggufs", tokenizer, quantization_method="q4_k_m")

다음과 같은 출력을 볼 수 있습니다:

==((====))==  Unsloth: Conversion from QLoRA to GGUF information
   \\   /|    [0] Installing llama.cpp will take 3 minutes.
O^O/ \_/ \    [1] Converting HF to GGUF 16bits will take 3 minutes.
\        /    [2] Converting GGUF 16bits to ['f16'] will take 10 minutes each.
 "-____-"     In total, you will have to wait at least 16 minutes.

Unsloth: [0] Installing llama.cpp. This will take 3 minutes...
Unsloth: [1] Converting model at lora-fused into f16 GGUF format.
The output location will be ./lora-fused/unsloth.F16.gguf

...

Writing: 100%|██████████| 7.64G/7.64G [01:18<00:00, 97.1Mbyte/s]
INFO:hf-to-gguf:Model successfully exported to lora-fused/unsloth.F16.gguf
Unsloth: Conversion completed! Output location: ./lora-fused/unsloth.F16.gguf

이것으로 끝입니다! 이제 파인튜닝된 텍스트-SQL 생성기를 갖게 되었습니다. 데이터 처리 스크립트를 최소한으로 변경하여 다른 작업에도 쉽게 적용할 수 있습니다.

여기서 더 나아가 다양한 강화 학습 기법을 사용하여 모델을 학습시켜 모델의 성능을 더욱 향상시킬 수도 있습니다.


원문 © Stephen Diehl, stephendiehl.com · 글 CC BY-SA 4.0, 코드 MIT · Stephen Diehl은 런던의 소프트웨어 엔지니어이자 작가입니다(저자가 정한 소개 문구). 이 글은 저자가 개인 자격으로 쓴 것이며 어떤 조직과의 연관도 밝히거나 암시해서는 안 됩니다 (라이선스와 고지).
이 페이지는 원문을 한국어로 옮기며 변경한 비공식 번역이며 같은 CC BY-SA 4.0으로 제공합니다 · yeokja 한국어 번역 · Anthropic 사의 claude-opus-5-5 모델을 활용하여 번역되었으며 학습을 모두 비허용한 상태로 작업하였습니다.