80바이트 옵티마이저 오차를 잡는 오픈소스 멀티모달 파인튜닝 실무 실행법
TuBrief 편집팀
2026년 8월 19일
0
컴퓨터/소프트웨어원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
커뮤니티의 다른 글
댓글 (0)
Log in to leave a comment
아직 작성된 글이 없습니다
원본 영상을 바탕으로 AI의 도움을 받아 작성했습니다. 원본 영상이 기준입니다.
Log in to leave a comment
아직 작성된 글이 없습니다
오픈웨이트 소형 멀티모달 모델은 비즈니스 데이터 학습 장벽을 낮췄습니다. 하지만 VRAM 계산 오차나 오디오 전처리 누락으로 훈련이 도중에 멈추는 상황이 반복됩니다. 하드웨어 예산 산정부터 오디오 전처리 파이프라인, 성능 검증 단계까지 실무에서 직접 작동하는 실행 방안을 짚어봅니다.
메모리 부족 오류를 막으려면 총 VRAM 점유량()을 모델 파라미터, 그래디언트, 옵티마이저 상태, 액티베이션, 프레임워크 오버헤드의 합으로 직접 계산해야 합니다.
표준 AdamW 옵티마이저는 학습 파라미터당 1차 모멘텀과 2차 분산을 FP32 정밀도로 저장하므로 를 소모합니다. 8-bit AdamW 라이브러리를 적용하면 이 소요량을 파라미터당 약 6바이트로 줄입니다. 8B 파라미터 모델을 FP16 정밀도로 전체 파인튜닝하면 약 120GB에서 140GB의 VRAM이 필요합니다. 다중 A100 80GB 장비가 강제되는 이유입니다.
단일 GPU 환경에서 예산을 아끼려면 다음 절차를 거칩니다.
노이즈가 섞인 로우 오디오를 멀티모달 인코더에 그대로 넣으면 손실 함수가 요동칩니다. EBU R128 표준에 따라 통합 음량을 -23 LUFS 오차 범위 1 LUFS 안으로 맞추거나 최고 피크를 -1.0 dBFS로 설정해 그래디언트 폭주를 막습니다.
샘플링 레이트()를 16000 Hz로 고정하고 FFT 윈도우 크기를 2048 샘플로 둡니다. 윈도우 오버랩을 60%에서 75% 수준으로 유지하도록 hop_length를 512 샘플로 지정해 초당 100개의 프레임을 만듭니다. Mel 필터뱅크는 128 채널을 적용하고 로그 압축을 거칩니다.
학습 중 NaN 텐서로 인한 비정상 종료를 막으려면 파이프라인 도입부에 아래 검증 스크립트를 배치합니다.
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
학습률은 모델 구조에 따라 다르게 잡아야 합니다. 전체 파인튜닝은 에서 사이, 랭크 인 LoRA는 에서 사이, QLoRA는 에서 사이로 설정합니다. 전체 스텝의 3%에서 5% 구간 동안 Linear Warmup을 넣고 이후 Cosine Decay로 감쇠시킵니다.
배치 사이즈를 4로 낮추더라도 gradient_accumulation_steps를 8로 두어 실효 배치 사이즈를 32로 유지합니다. 과적합을 막으려면 아래 HuggingFace Trainer 구성을 그대로 적용합니다.
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"와 eval_steps=100을 걸어 100스텝마다 손실을 추적합니다.load_best_model_at_end=True를 켜서 검증 손실이 가장 낮았던 가중치를 자동으로 남깁니다.EarlyStoppingCallback에 early_stopping_patience=3을 부여해 검증 손실이 연속 3회 개선되지 않으면 연산을 즉시 멈춥니다.모델 배포 전에는 도메인 특화 프롬프트 10가지로 응답 품질을 확인해야 합니다. 오디오 시간축 위치 파악, 노이즈 환경 텍스트 추출, 시각적 객체 상태 분석, 시각-오디오 이벤트 동시성, 복합 턴 멀티모달 지시, 도메인 전문 용어 처리, 비음성 음향 이벤트 추론, 공간적 관계 인식, 도메인 외 환각 유도 검증, 정형 데이터 JSON 출력 테스트를 수행합니다.
객체 환각은 CHAIR 프레임워크와 POPE 프레임워크로 측정합니다.
POPE 프레임워크에서는 Random, Popular, Adversarial Sampling 질의를 통해 예스오로 노 답변 정확도를 측정합니다. 프로덕션 환경에 올리기 전에는 첫 토큰 생성 시간 800ms 이내 확보, 초당 토큰 생성 속도 30토큰 유지, vLLM 변환 후 JSON 출력 규격 유지 여부를 최종 확인합니다.