Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dieses Notizbuch veranschaulicht die überwachte Feinabstimmung (SFT) des großen GPT-OSS-Modells mit 120 Milliarden Parametern mithilfe von 8 H100 GPUs und Databricks Serverless GPU Compute. Die Schulung nutzt:
- FSDP (Fully Sharded Data Parallel): Shards-Modellparameter, Farbverläufe und Optimiererzustände über GPUs hinweg, um die Schulung großer Modelle zu ermöglichen, die nicht auf eine einzelne GPU passen.
- DDP (Distributed Data Parallel): Verteilt Schulungen auf mehrere GPUs für schnellere Schulungen.
- LoRA (Low-Rank Adaption): Reduziert die Anzahl trainierbarer Parameter durch Hinzufügen kleiner Adapterschichten, wodurch Feinabstimmungen effizienter werden.
- TRL (Transformers Reinforcement Learning): Stellt den SFTTrainer für überwachte Feinabstimmung bereit.
Durch Festlegen remote=False und Angeben von 16 GPUs kann dies auf mehrknotenübergreifende Schulungen über 16 GPUs erweitert werden.
Installieren Sie die erforderlichen Pakete
Installieren Sie die erforderlichen Bibliotheken für verteilte Schulungen und Modelloptimierungen:
-
trl: Transformers Verstärkungslernbibliothek für SFT-Schulungen -
peft: Parameter-Efficient Fine-Tuning für LoRA-Adapter -
transformers: Hugging Face Transformers Library -
datasets: Zum Laden von Schulungsdatensätzen -
accelerate: Für verteilte Trainings-Orchestrierung -
hf_transfer: Für schnellere Modelldownloads von Hugging Face
%pip install "trl==1.1.0"
%pip install "peft==0.19.1"
%pip install "transformers==5.5.4"
%pip install "fsspec==2024.9.0"
%pip install "huggingface_hub==1.11.0"
%pip install "datasets==3.2.0"
%pip install "accelerate==1.13.0"
%restart_python
Definieren der verteilten Schulungsfunktion mit FSDP
Diese Zelle definiert die Schulungsfunktion, die mit dem @distributed Dekorierer auf 8 H100 GPUs ausgeführt wird. Die Funktion umfasst Folgendes:
- Modell laden: Lädt das 120B-Parameter GPT-OSS Modell in bfloat16-Präzision
- LoRA-Konfiguration: Wendet Low-Rank-Anpassung mit Rangstufe 16 an, um die Anzahl der zu trainierenden Parameter zu verringern
- FSDP-Setup: Konfiguriert vollständig partitionierte Datenparallelität mit automatischem Layerumbruch und Aktivierungs-Checkpointing
- Trainingskonfiguration: Legt die Batchgröße, die Lernrate, die Gradientenakkumulation und andere Hyperparameter fest.
- Dataset: Verwendet das Dataset HuggingFaceH4/Multilingual-Thinking zur Feinabstimmung
Die Funktion erkennt automatisch Transformatorblockklassen für die FSDP-Einbettung und koordiniert das verteilte Training über alle GPUs hinweg.
dbutils.widgets.text("uc_catalog", "main")
dbutils.widgets.text("uc_schema", "default")
dbutils.widgets.text("uc_model_name", "gpt-oss-120b-peft")
dbutils.widgets.text("uc_volume", "checkpoints")
dbutils.widgets.text("model", "openai/gpt-oss-120b")
dbutils.widgets.text("dataset_path", "HuggingFaceH4/Multilingual-Thinking")
UC_CATALOG = dbutils.widgets.get("uc_catalog")
UC_SCHEMA = dbutils.widgets.get("uc_schema")
UC_MODEL_NAME = dbutils.widgets.get("uc_model_name")
UC_VOLUME = dbutils.widgets.get("uc_volume")
HF_MODEL_NAME = dbutils.widgets.get("model")
DATASET_PATH = dbutils.widgets.get("dataset_path")
print(f"UC_CATALOG: {UC_CATALOG}")
print(f"UC_SCHEMA: {UC_SCHEMA}")
print(f"UC_MODEL_NAME: {UC_MODEL_NAME}")
print(f"UC_VOLUME: {UC_VOLUME}")
print(f"HF_MODEL_NAME: {HF_MODEL_NAME}")
print(f"DATASET_PATH: {DATASET_PATH}")
OUTPUT_DIR = f"/Volumes/{UC_CATALOG}/{UC_SCHEMA}/{UC_VOLUME}/{UC_MODEL_NAME}"
print(f"OUTPUT_DIR: {OUTPUT_DIR}")
from serverless_gpu import distributed
@distributed(gpus=8, gpu_type='H100')
def train_gpt_oss_fsdp_120b():
"""
Fine-tune a 120B-class model with TRL SFTTrainer + FSDP2 on H100s.
Uses LoRA + activation ckpt + full_shard auto_wrap.
"""
# --- imports inside for pickle safety ---
import os, torch, torch.distributed as dist
from transformers import AutoModelForCausalLM, AutoTokenizer, Mxfp4Config
from trl import SFTTrainer, SFTConfig
from datasets import load_dataset
from peft import LoraConfig, get_peft_model
# ---------- DDP / CUDA binding ----------
local_rank = int(os.environ.get("LOCAL_RANK", "0"))
torch.cuda.set_device(local_rank)
os.environ.setdefault("TOKENIZERS_PARALLELISM", "false")
os.environ.setdefault("NCCL_DEBUG", "WARN")
os.environ.setdefault("CUDA_LAUNCH_BLOCKING", "0")
os.environ.setdefault("TORCH_NCCL_ASYNC_ERROR_HANDLING", "1") # replaces NCCL_ASYNC_ERROR_HANDLING
# ---------- Config ----------
MAX_LENGTH = 2048
PER_DEVICE_BATCH = 1 # start conservative for 120B
GRAD_ACCUM = 4 # tune for throughput
LR = 1.5e-4
EPOCHS = 1
is_main = int(os.environ.get("RANK", "0")) == 0
world_size = int(os.environ.get("WORLD_SIZE", "1"))
if is_main:
print("=" * 60)
print("FSDP (full_shard) launch for 120B")
print(f"WORLD_SIZE={world_size} | LOCAL_RANK={local_rank}")
print("=" * 60)
# ---------- Tokenizer ----------
tokenizer = AutoTokenizer.from_pretrained(HF_MODEL_NAME)
if tokenizer.pad_token_id is None and tokenizer.eos_token_id is not None:
tokenizer.pad_token = tokenizer.eos_token
tokenizer.model_max_length = MAX_LENGTH
tokenizer.truncation_side = "right"
# ---------- Model ----------
# IMPORTANT: no device_map, no .to(device) — let Trainer/Accelerate+FSDP handle placement
# low_cpu_mem_usage helps with massive checkpoints (still needs decent host RAM)
quantization_config = Mxfp4Config(dequantize=True)
model = AutoModelForCausalLM.from_pretrained(
HF_MODEL_NAME,
dtype=torch.bfloat16,
attn_implementation="eager",
quantization_config=quantization_config,
use_cache=False, # needed for grad ckpt
low_cpu_mem_usage=True,
)
# ---------- LoRA ----------
# the following config works
# include MoE layers as well.
peft_config = LoraConfig(
r=32,
lora_alpha=32,
target_modules="all-linear",
rank_pattern={
"mlp.experts.gate_up_proj": 8,
"mlp.experts.down_proj": 8
},
target_parameters=["mlp.experts.gate_up_proj", "mlp.experts.down_proj"],
lora_dropout=0.0,
bias="none",
task_type="CAUSAL_LM",
)
model = get_peft_model(model, peft_config)
# Cast all parameters to bfloat16 so FSDP sees a uniform dtype
# (LoRA adapters are initialized in float32 by default)
model = model.to(torch.bfloat16)
if is_main:
model.print_trainable_parameters()
# ---------- Data ----------
dataset = load_dataset("HuggingFaceH4/Multilingual-Thinking", split="train")
if is_main:
print(f"Dataset size: {len(dataset)}")
# ---------- FSDP settings ----------
def infer_transformer_blocks_for_fsdp(model):
COMMON = {
"LlamaDecoderLayer", "MistralDecoderLayer", "MixtralDecoderLayer",
"Qwen2DecoderLayer", "Gemma2DecoderLayer", "Phi3DecoderLayer",
"GPTNeoXLayer", "MPTBlock", "BloomBlock", "FalconDecoderLayer",
"DecoderLayer", "GPTJBlock", "OPTDecoderLayer"
}
hits = set()
for _, m in model.named_modules():
name = m.__class__.__name__
if name in COMMON:
hits.add(name)
# Fallback: grab anything that *looks* like a decoder block
if not hits:
for _, m in model.named_modules():
name = m.__class__.__name__
if any(s in name for s in ["Block", "DecoderLayer", "Layer"]) and "Embedding" not in name:
hits.add(name)
return sorted(hits)
fsdp_wrap_classes = infer_transformer_blocks_for_fsdp(model)
if not fsdp_wrap_classes:
raise RuntimeError("Could not infer transformer block classes for FSDP wrapping; "
"print(model) and add the block class explicitly.")
training_args = SFTConfig(
output_dir=OUTPUT_DIR,
num_train_epochs=EPOCHS,
per_device_train_batch_size=PER_DEVICE_BATCH,
gradient_accumulation_steps=GRAD_ACCUM,
learning_rate=LR,
warmup_ratio=0.03,
lr_scheduler_type="cosine",
bf16=True,
logging_steps=5,
logging_strategy="steps",
save_strategy="no",
report_to="none",
ddp_find_unused_parameters=False,
dataloader_pin_memory=True,
max_length=MAX_LENGTH,
gradient_checkpointing=False,
# ---- FSDP2 knobs ----
fsdp="full_shard auto_wrap",
fsdp_config={
"version": 2,
"fsdp_transformer_layer_cls_to_wrap": fsdp_wrap_classes,
"reshard_after_forward": True,
"activation_checkpointing": True, # <- use activation ckpt (not gradient)
"xla": False,
"limit_all_gathers": True,
},
)
# ---------- Trainer ----------
trainer = SFTTrainer(
model=model,
args=training_args,
train_dataset=dataset,
processing_class=tokenizer,
)
# verify distributed init & FSDP
rank = int(os.getenv("RANK", "0"))
print(f"[rank {rank}] dist.is_initialized() -> {dist.is_initialized()}")
acc = getattr(trainer, "accelerator", None)
print(f"[rank {rank}] accelerator.distributed_type = {getattr(getattr(acc,'state',None),'distributed_type','n/a')}")
print(f"[rank {rank}] accelerator.num_processes = {getattr(acc, 'num_processes', 'n/a')}")
# ---------- Train ----------
result = trainer.train()
if is_main:
print("\nTraining complete (FSDP).")
print(result.metrics)
Den verteilten Trainingsjob ausführen
Führen Sie die Schulungsfunktion auf 8 H100 GPUs aus. Der @distributed Dekorateur übernimmt die Orchestrierung des Trainings über alle GPUs mit ordnungsgemäß verteilter Einrichtung.
train_gpt_oss_fsdp_120b.distributed()
Nächste Schritte
- Multi-GPU- und Multi-Node-Verteiltes Training
- Bewährte Methoden für serverlose GPU-Compute
- Fehlerbehebung bei Serverless GPU Compute
- PEFT-Dokumentation
- TRL-Dokumentation