Steering이 작동하는 이유: LLM 파라미터 다이나믹스의 통합 관점
Why Steering Works: Toward a Unified View of Language Model Parameter Dynamics
TL;DR Highlight
Fine-tuning, LoRA, Activation Steering을 하나의 수식으로 통합하고, 제어 강도를 높일수록 왜 모델 품질이 떨어지는지 수학적으로 설명한 뒤 개선된 학습 목적함수 SPLIT을 제안한다.
Who Should Read
LLM 동작을 제어하거나 커스터마이징하는 ML 엔지니어 및 연구자. 특히 activation steering이나 LoRA 파인튜닝 시 제어 강도를 높였더니 출력이 이상해지는 문제를 경험한 분.
Core Mechanics
- Fine-tuning, LoRA, Activation Steering 세 가지 방법이 모두 `h_new = (W + m·ΔW)·h + (b + m·Δb)` 하나의 수식으로 표현됨 — 방법론 차이는 어떤 항을 건드리느냐의 차이일 뿐
- 제어 효과를 'preference(목표 개념 방향으로 생성하려는 경향)'와 'utility(출력이 문법적이고 지시를 따르는 정도)'로 분리해 log-odds 척도로 측정하는 분석 프레임워크 제시
- 제어 강도(m)를 키우면 preference는 오르고 utility는 내려가는 trade-off 패턴이 세 방법 모두에서 동일하게 나타남 — 방법론과 무관한 보편적 현상
- Activation manifold(모델이 정상 입력에서 만드는 내부 표현의 전형적인 분포 영역) 관점: 스티어링이 표현을 이 영역 밖으로 밀어낼수록 utility가 감소
- 이 메커니즘을 바탕으로 SPLIT 학습 목적함수 제안 — utility 보존 loss(positive/negative 쌍 크로스엔트로피)와 preference 향상 loss(hinge 마진)를 결합
- Gemma-2-9B-IT, Qwen-2.5-7B-Instruct 두 모델에서 Local Weight / LoRA / Vector 세 방식 모두에 적용 가능하며, 기존 SFT·RePS 대비 일관되게 개선
Evidence
- Preference/Utility 곡선 피팅 R² > 0.95 (대부분 설정), Utility R² > 0.97 — 수식이 실험 데이터를 잘 설명함을 검증
- Gemma-2-9B-IT Vector 방식: SPLIT Harmonic Mean 1.6475 vs SFT 1.4487, RePS 1.5550 (AxBench 기준)
- Qwen-2.5-7B-IT LoRA 방식: SPLIT Harmonic Mean 1.6362 vs SFT 1.3175, RePS 1.4013 (AxBench 기준)
- Psychopathy 분류 정확도: SPLIT 98~100% 달성, Vanilla(무개입) 대비 50%p 이상 개선
How to Apply
- Activation steering 강도(m) 조절 시 무작정 올리지 말고, validation 세트에서 preference/utility log-odds를 함께 모니터링해 utility가 급락하기 직전 지점을 찾아 사용
- LoRA나 local weight steering으로 모델 행동을 바꿀 때 SPLIT 목적함수 적용: positive/negative 응답 쌍을 준비하고 `L = λ_p·L_pos + λ_n·L_neg + γ·ReLU(θ - (L_neg - L_pos))` 로 학습
- 세 방법(fine-tuning, LoRA, steering vector) 중 선택할 때 이 논문의 unified view를 참고 — 근본적으로 같은 메커니즘이므로 데이터 규모·지연 요구사항 기준으로만 선택해도 충분
Code Example
# SPLIT 목적함수 핵심 구현 예시 (PyTorch)
import torch
import torch.nn.functional as F
def split_loss(
logits_pos, # positive 샘플에 대한 모델 출력 logits
logits_neg, # negative 샘플에 대한 모델 출력 logits
labels_pos, # positive 샘플 토큰 레이블
labels_neg, # negative 샘플 토큰 레이블
lambda_p=1.0, lambda_n=1.0, # utility loss 가중치
gamma=1.0, # preference loss 강도
theta=1.0, # preference 마진 임계값
):
# Utility Loss: positive/negative 모두 잘 생성하도록
L_pos = F.cross_entropy(logits_pos.view(-1, logits_pos.size(-1)), labels_pos.view(-1))
L_neg = F.cross_entropy(logits_neg.view(-1, logits_neg.size(-1)), labels_neg.view(-1))
L_util = lambda_p * L_pos + lambda_n * L_neg
# Preference Loss: negative loss - positive loss 차이(preference log-odds)를 margin 이상으로 키우기
pref_log_odds = L_neg - L_pos # 높을수록 positive 쪽 선호
L_pref = gamma * F.relu(theta - pref_log_odds) # hinge loss
return L_util + L_pref
# 사용 예시
# loss = split_loss(model(pos_input), model(neg_input), pos_labels, neg_labels)Terminology
Related Resources
Original Abstract (Expand)
Methods for controlling large language models (LLMs), including local weight fine-tuning, LoRA-based adaptation, and activation-based interventions, are often studied in isolation, obscuring their connections and making comparison difficult. In this work, we present a unified view that frames these interventions as dynamic weight updates induced by a control signal, placing them within a single conceptual framework. Building on this view, we propose a unified preference-utility analysis that separates control effects into preference, defined as the tendency toward a target concept, and utility, defined as coherent and task-valid generation, and measures both on a shared log-odds scale using polarity-paired contrastive examples. Across methods, we observe a consistent trade-off between preference and utility: stronger control increases preference while predictably reducing utility. We further explain this behavior through an activation manifold perspective, in which control shifts representations along target-concept directions to enhance preference, while utility declines primarily when interventions push representations off the model's valid-generation manifold. Finally, we introduce a new steering approach SPLIT guided by this analysis that improves preference while better preserving utility. Code is available at https://github.com/zjunlp/EasyEdit/blob/main/examples/SPLIT.md.