Panduan Praktis Fine-Tuning Multimodal Open-Source untuk Mengatasi Galat Optimizer 80-Byte
TuBrief 편집팀
2026년 8월 19일
0
Computing/Software원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
Model multimodal kecil berbobot terbuka (open-weight) telah menurunkan hambatan untuk melatih data bisnis. Namun, pelatihan sering kali terhenti di tengah jalan karena galat perhitungan VRAM atau kelalaian dalam pra-pemrosesan audio. Artikel ini mengupas tuntas metode praktis yang langsung dapat diterapkan di lapangan, mulai dari estimasi anggaran perangkat keras, pipa (pipeline) pra-pemrosesan audio, hingga tahap verifikasi performa.
Untuk mencegah galat kehabisan memori (Out-Of-Memory), total penggunaan VRAM () harus dihitung secara langsung sebagai jumlah dari parameter model, gradien, status optimizer, aktivasi, dan overhead kerangka kerja.
Optimizer AdamW standar menyimpan momentum pertama dan varians kedua per parameter pelatihan dalam presisi FP32, sehingga mengonsumsi . Menerapkan pustaka 8-bit AdamW mengurangi kebutuhan ini menjadi sekitar 6 byte per parameter. Melakukan fine-tuning penuh pada model 8B parameter dalam presisi FP16 membutuhkan VRAM sekitar 120GB hingga 140GB. Inilah alasan mengapa penggunaan beberapa perangkat A100 80GB sering kali diwajibkan.
Untuk menghemat anggaran dalam lingkungan GPU tunggal, ikuti langkah-langkah berikut:
Jika audio mentah yang bercampur derau (noise) dimasukkan begitu saja ke encoder multimodal, fungsi kerugian (loss function) akan berfluktuasi tidak stabil. Sesuai dengan standar EBU R128, sesuaikan kenyaringan terintegrasi (integrated loudness) ke -23 LUFS dalam rentang galat 1 LUFS atau tetapkan puncak tertinggi (peak) ke -1.0 dBFS untuk mencegah ledakan gradien (gradient explosion).
Tetapkan tingkat pengambilan sampel () pada 16000 Hz dan ukuran jendela FFT pada 2048 sampel. Tentukan hop_length sebesar 512 sampel untuk menjaga tumpang tindih jendela (window overlap) pada tingkat 60% hingga 75%, sehingga menghasilkan 100 bingkai per detik. Terapkan 128 saluran untuk bank filter Mel dan lakukan kompresi logaritmik.
Untuk mencegah penghentian abnormal yang disebabkan oleh tensor NaN selama pelatihan, tempatkan skrip verifikasi berikut di awal pipa:
`python
import os
import json
import torch
import torchaudio
from PIL import Image
def validate_multimodal_dataset(jsonl_path, min_audio_len=0.5, max_audio_len=30.0):
valid_records = []
corrupted_count = 0
with open(jsonl_path, 'r', encoding='utf-8') as f:
lines = f.readlines()
for idx, line in enumerate(lines):
try:
data = json.loads(line.strip())
audio_path = data.get("audio_path")
image_path = data.get("image_path")
text_label = data.get("text")
if not text_label or not isinstance(text_label, str) or len(text_label.strip()) == 0:
raise ValueError("Empty or invalid text label.")
if audio_path and os.path.exists(audio_path):
info = torchaudio.info(audio_path)
duration = info.num_frames / info.sample_rate
if duration < min_audio_len or duration > max_audio_len:
raise ValueError(f"Audio duration {duration:.2f}s out of bounds.")
waveform, sr = torchaudio.load(audio_path)
if torch.isnan(waveform).any() or torch.isinf(waveform).any():
raise ValueError("Audio contains NaN/Inf values.")
elif audio_path:
raise FileNotFoundError(f"Audio path not found: {audio_path}")
if image_path and os.path.exists(image_path):
with Image.open(image_path) as img:
img.verify()
with Image.open(image_path) as img:
img.convert("RGB")
width, height = img.size
if width < 10 or height < 10:
raise ValueError(f"Image resolution too small: {width}x{height}")
elif image_path:
raise FileNotFoundError(f"Image path not found: {image_path}")
valid_records.append(data)
except Exception as e:
corrupted_count += 1
return valid_records
`
Learning rate harus diatur secara berbeda tergantung pada struktur model. Tetapkan antara hingga untuk fine-tuning penuh, antara hingga untuk LoRA dengan peringkat , dan antara hingga untuk QLoRA. Terapkan Linear Warmup selama 3% hingga 5% dari total langkah, lalu kurangi dengan Cosine Decay setelahnya.
Meskipun ukuran batch dikurangi menjadi 4, pertahankan gradient_accumulation_steps pada 8 agar ukuran batch efektif tetap berada di angka 32. Untuk mencegah overfitting, terapkan konfigurasi HuggingFace Trainer berikut secara langsung:
`python
from transformers import (
Trainer,
TrainingArguments,
EarlyStoppingCallback
)
training_args = TrainingArguments(
output_dir="./fine_tuned_multimodal_checkpoints",
num_train_epochs=5,
per_device_train_batch_size=4,
per_device_eval_batch_size=4,
gradient_accumulation_steps=8,
learning_rate=2e-4,
weight_decay=0.01,
warmup_ratio=0.03,
lr_scheduler_type="cosine",
logging_steps=10,
eval_strategy="steps",
eval_steps=100,
save_strategy="steps",
save_steps=100,
save_total_limit=3,
load_best_model_at_end=True,
metric_for_best_model="eval_loss",
greater_is_better=False,
fp16=True,
report_to="wandb"
)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset,
eval_dataset=val_dataset,
data_collator=data_collator,
callbacks=[
EarlyStoppingCallback(
early_stopping_patience=3,
early_stopping_threshold=0.001
)
]
)
trainer.train()
`
eval_strategy="steps" dan eval_steps=100 untuk melacak loss setiap 100 langkah.load_best_model_at_end=True untuk secara otomatis mempertahankan bobot dengan validation loss terendah.early_stopping_patience=3 pada EarlyStoppingCallback untuk segera menghentikan komputasi jika validation loss tidak menunjukkan peningkatan selama 3 kali berturut-turut.Sebelum menerapkan model, kualitas respons harus diverifikasi menggunakan 10 jenis prompt khusus domain. Lakukan pelacakan posisi sumbu waktu audio, ekstraksi teks lingkungan berderau, analisis status objek visual, konkurensi peristiwa visual-audio, instruksi multimodal multi-turn kompleks, penanganan istilah khusus domain, inferensi peristiwa akustik non-verbal, pengenalan hubungan spasial, verifikasi induksi halusinasi di luar domain (out-of-domain), serta pengujian keluaran JSON data terstruktur.
Halusinasi objek diukur menggunakan kerangka kerja CHAIR dan POPE.
CHAIR_i = rac{ ext{Jumlah instans objek halusinasi}}{ ext{Total instans objek yang disebutkan}}CHAIR_s = rac{ ext{Jumlah takarir (caption) yang berisi 1 atau lebih objek halusinasi}}{ ext{Total takarir yang dievaluasi}}Dalam kerangka kerja POPE, akurasi jawaban ya/tidak (yes/no) diukur melalui kueri Random, Popular, dan Adversarial Sampling. Sebelum menaikkannya ke lingkungan produksi, lakukan konfirmasi akhir untuk memastikan waktu pembuatan token pertama di bawah 800ms, mempertahankan kecepatan pembuatan 30 token per detik, serta menjaga kepatuhan spesifikasi keluaran JSON setelah konversi vLLM.