콘텐츠로 이동
Data Prep
상세

Training Data Attribution

메타 정보

항목 내용
분류 Data-Centric AI / Interpretable ML / Model Debugging
핵심 논문 "Understanding Black-box Predictions via Influence Functions" (Koh & Liang, ICML 2017)
주요 저자 Pang Wei Koh, Percy Liang (Stanford), Sung Min Park, Aleksander Madry (MIT), Roger Grosse (U of T)
핵심 개념 모델 예측을 학습 데이터로 역추적 -- 각 학습 샘플의 기여도 정량화
관련 시스템 TRAK, TracIn, EK-FAC, TrackStar, LoGra, AirRep
관련 분야 Data Valuation, Explainable AI, Model Debugging, Copyright Attribution

정의

Training Data Attribution (TDA)은 모델의 특정 예측에 대해 각 학습 데이터 포인트가 얼마나 기여했는지를 정량화하는 기법이다. 핵심 질문은 "이 예측 결과에 어떤 학습 데이터가 가장 큰 영향을 미쳤는가?"이다.

핵심 프레임워크:

모델 f(x; theta)가 학습 데이터 D = {z_1, ..., z_n}으로 학습됨
테스트 샘플 z_test에 대해

  TDA 목표: alpha_i = 학습 샘플 z_i가 f(z_test)에 미친 영향

직관적 이해:
  - alpha_i > 0: z_i가 현재 예측을 "지지"
  - alpha_i < 0: z_i가 현재 예측에 "반대"
  - |alpha_i|: 영향력의 크기

이상적 방법 (Gold Standard):
  Leave-One-Out (LOO):
    z_i 제거 후 재학습 -> 예측 변화 측정
    비용: O(n)회 전체 재학습 -> 대규모 모델에서 불가능

현실적 방법:
  LOO를 효율적으로 "근사"하는 다양한 기법들

배경: 왜 Training Data Attribution인가

모델 디버깅의 필요성

상황: LLM이 잘못된 사실을 생성 (hallucination)

전통적 접근:
  "왜 이런 출력이 나왔지?" -> 모델 아키텍처/학습 과정 분석
  -> 원인 특정 어려움

TDA 접근:
  "어떤 학습 데이터가 이 출력에 기여했는가?" -> 직접 추적
  -> 문제 데이터 식별 -> 제거/수정 후 재학습

핵심 응용:
  1. 데이터 품질 디버깅: 레이블 오류, 노이즈 데이터 탐지
  2. 저작권 추적: 생성 결과의 원본 데이터 출처 확인
  3. 데이터 가치 평가: 개별 데이터의 경제적 가치 측정
  4. 모델 해석: 예측 근거를 학습 데이터로 설명
  5. 안전성: 유해 출력의 원인 데이터 추적

데이터 규모 문제

모델 크기 증가에 따른 TDA 난이도:

MNIST (1990s):
  학습 데이터: 60,000
  파라미터: ~10^4
  LOO 재학습: 실현 가능

ImageNet + ResNet (2010s):
  학습 데이터: 1,200,000
  파라미터: ~10^7
  LOO 재학습: 수개월 소요 -> Influence Functions 필요

GPT-3 / LLaMA (2020s):
  학습 데이터: ~10^12 토큰
  파라미터: ~10^10 - 10^11
  LOO 재학습: 완전 불가능 -> 확장 가능한 근사 방법 필수

연구 방향: 정확도를 유지하면서 계산 비용을 줄이는 방법

핵심 방법론

1. Influence Functions (ICML 2017)

핵심 아이디어:
  LOO 재학습을 Hessian 기반으로 근사

수학적 정의:
  I(z_i, z_test) = -nabla_theta L(z_test, theta_hat)^T
                    * H_theta_hat^{-1}
                    * nabla_theta L(z_i, theta_hat)

  여기서:
    theta_hat: 전체 데이터로 학습된 최적 파라미터
    H_theta_hat: Hessian 행렬 = nabla^2_theta (1/n) sum_i L(z_i, theta)
    nabla_theta L: 파라미터에 대한 손실의 그래디언트

직관:
  1. 테스트 손실의 그래디언트: "theta가 어느 방향으로 가면 테스트 손실이 줄까?"
  2. Hessian 역행렬: "파라미터 공간의 곡률 보정"
  3. 학습 그래디언트와 내적: "z_i가 theta를 그 방향으로 밀었는가?"

계산 병목:
  H^{-1} 계산: O(p^3) 직접 역행렬 -> 불가능 (p = 파라미터 수)

  해결: Implicit Hessian-Vector Product (HVP)
    LiSSA: 반복적 근사 (Koh & Liang, 2017)
    Conjugate Gradient: 정확도 높은 근사
    EK-FAC: Kronecker 분해 기반 (Grosse et al., 2023)
    Arnoldi Iteration: 대규모 모델용 (Schioppa et al., 2022)

한계:
  - 볼록 손실 가정 (딥러닝은 비볼록)
  - damping 하이퍼파라미터에 민감
  - 대규모 모델에서 근사 오차 누적

2. TracIn (NeurIPS 2020)

핵심 아이디어:
  학습 과정의 체크포인트별 그래디언트 내적으로 영향력 추적

수학적 정의:
  TracIn(z_i, z_test) = sum_{t: z_i in B_t} eta_t
                         * nabla_theta L(z_test, theta_t)
                         . nabla_theta L(z_i, theta_t)

  여기서:
    t: 학습 스텝
    B_t: 시점 t의 미니배치
    eta_t: 학습률
    theta_t: 시점 t의 파라미터

직관:
  z_i가 미니배치에 포함된 각 스텝에서
  "z_i의 업데이트가 z_test의 손실을 얼마나 줄였는가?"의 누적

장점:
  - Hessian 계산 불필요 (1차 그래디언트만)
  - 구현 단순
  - 학습 궤적 정보 활용

단점:
  - 체크포인트 저장 필요 (저장 비용)
  - 체크포인트 수에 따라 정확도 변동
  - 전체 그래디언트 벡터 사용 -> 메모리 부담

실용적 근사: TracIn-CP
  체크포인트 k개만 사용:
  TracIn-CP = sum_{j=1}^{k} eta_j
               * nabla_theta L(z_test, theta_j) . nabla_theta L(z_i, theta_j)

  k = 3~10 정도면 합리적 근사 가능

3. TRAK (ICML 2023)

핵심 아이디어:
  랜덤 프로젝션 + 커널 근사로 확장 가능한 TDA

방법:
  1. 각 샘플의 그래디언트를 저차원 공간으로 프로젝션
     phi(z) = P * nabla_theta L(z, theta)  (P: 랜덤 행렬, p -> d)

  2. 선형 데이터모델로 귀속 점수 계산
     TRAK(z_i, z_test) = phi(z_test)^T * (Phi^T Phi + lambda I)^{-1} * phi(z_i)

  3. 여러 체크포인트에서 앙상블
     최종 점수 = (1/M) sum_{m=1}^{M} TRAK_m(z_i, z_test)

이론적 기반: Neural Tangent Kernel (NTK) 근사
  - 넓은 네트워크에서 학습 동역학을 선형화
  - 랜덤 프로젝션으로 NTK 커널을 효율적으로 근사
  - Johnson-Lindenstrauss 보조정리에 의한 거리 보존

핵심 혁신:
  - 그래디언트 차원 p (~10^9) -> 프로젝션 차원 d (~2048)
  - 메모리: O(nd) vs O(np) -- 수천 배 절감
  - 사전 계산 후 새 테스트 샘플에 대해 O(d) 시간 귀속

평가 지표: Linear Datamodeling Score (LDS)
  - 무작위 부분집합으로 학습한 모델들의 실제 예측과
    TDA 점수 기반 예측의 상관관계
  - TRAK LDS: CIFAR-10에서 0.70 (Influence Functions: 0.58)

성능:
  모델           | 시간 (1 GPU)  | LDS
  --------------|-------------|------
  ResNet-9      | ~2시간       | 0.70
  CLIP (ViT-B)  | ~8시간       | 0.61
  mT5           | ~12시간      | 0.55

4. EK-FAC Influence (ICML 2023)

핵심 아이디어:
  Eigenvalue-corrected Kronecker-Factored Approximate Curvature

Hessian 역행렬의 효율적 근사:
  기존 IF: H^{-1} 직접 근사 -> 불안정, 느림
  EK-FAC: H를 Kronecker 곱으로 분해

  H ≈ Q * Lambda * Q^T  (Kronecker 구조의 고유값 분해)

Grosse et al. (2023)의 기여:
  - GPT-2 XL (1.5B)까지 확장
  - Gauss-Newton 근사 + Kronecker 분해
  - 쿼리 독립적 사전 계산 -> 빠른 귀속

한계:
  - 레이어별 독립성 가정
  - 근사 오차가 대규모 모델에서 누적

5. TrackStar (ICLR 2025)

핵심 아이디어:
  LLM 사전학습까지 확장한 그래디언트 기반 TDA

핵심 기술:
  1. 랜덤 프로젝션 (TRAK과 유사)
  2. Query-Batching: 여러 테스트 쿼리를 동시 처리
  3. Task-specific metric correction: 태스크에 맞는 보정

성과:
  - 8B 파라미터 LLM에 적용
  - 160B 토큰 코퍼스에서 귀속 수행
  - Fact Tracing: LLM의 사실적 예측을 학습 데이터로 역추적

주요 발견 (Chang et al., ICLR 2025):
  - 모델 크기가 클수록 귀속이 사실적 근거와 더 일치
  - 더 많은 데이터로 학습할수록 영향력이 특정 소스에 집중
  - "모델이 커지면 학습 데이터를 더 효율적으로 활용"

6. LoGra (NeurIPS 2024)

핵심 아이디어:
  역전파의 그래디언트 구조를 활용한 효율적 프로젝션

기존 방법의 문제:
  전체 그래디언트 벡터 계산 -> 메모리 O(p) -> LLM에서 불가능

LoGra 접근:
  - 역전파 과정에서 직접 프로젝트된 그래디언트 계산
  - 전체 그래디언트를 메모리에 올리지 않음
  - LoRA 스타일의 저랭크 구조 활용

결과:
  - GPT-2 (124M) ~ LLaMA-2 (7B)에서 검증
  - Influence Functions의 정확도 유지
  - 메모리 사용량 10배 이상 절감

방법론 비교

방법              | 핵심 원리       | Hessian | 확장성   | 정확도(LDS) | 최대 검증 모델
-----------------|---------------|---------|---------|-----------|-------------
Influence Func.  | 2차 근사       | O       |  낮음   | ~0.58     | GPT-2 (1.5B)
TracIn           | 체크포인트 내적  | X       |  중간   | ~0.50     | BERT
TRAK             | 랜덤 프로젝션   | X       |  높음   | ~0.70     | CLIP, mT5
EK-FAC           | Kronecker 분해 | 근사     |  중상   | ~0.62     | GPT-2 XL (1.5B)
TrackStar        | 보정 프로젝션   | X       | 매우 높음| ~0.65     | LLaMA (8B)
LoGra            | 구조적 프로젝션  | 근사     |  높음   | ~0.60     | LLaMA-2 (7B)
AirRep           | 학습 인코더     | X       | 매우 높음| ~0.68     | LLaMA-2 (7B)

정확도-비용 트레이드오프:
  TRAK, TrackStar: 가장 좋은 균형
  Influence Functions: 이론적으로 가장 정확하나 비용 높음
  AirRep: 추론 시 가장 빠르나 사전 학습 필요

Python 구현 예시

Influence Functions (LiSSA 근사)

import torch
import torch.nn.functional as F
from torch.autograd import grad
from typing import List, Tuple

def compute_gradient(
    model: torch.nn.Module,
    loss_fn,
    x: torch.Tensor,
    y: torch.Tensor
) -> torch.Tensor:
    """단일 샘플의 파라미터 그래디언트를 평탄화된 벡터로 반환"""
    model.zero_grad()
    output = model(x.unsqueeze(0))
    loss = loss_fn(output, y.unsqueeze(0))
    grads = grad(loss, model.parameters(), create_graph=False)
    return torch.cat([g.flatten() for g in grads])


def hessian_vector_product(
    model: torch.nn.Module,
    loss_fn,
    data_loader: torch.utils.data.DataLoader,
    v: torch.Tensor,
    device: str = "cpu"
) -> torch.Tensor:
    """
    미니배치 기반 Hessian-Vector Product 계산
    H * v 를 역전파로 효율적으로 구함
    """
    hvp = torch.zeros_like(v)
    n_batches = 0

    for x_batch, y_batch in data_loader:
        x_batch, y_batch = x_batch.to(device), y_batch.to(device)
        model.zero_grad()
        output = model(x_batch)
        loss = loss_fn(output, y_batch)

        # 1차 그래디언트
        grads = grad(loss, model.parameters(), create_graph=True)
        flat_grads = torch.cat([g.flatten() for g in grads])

        # v와의 내적 후 2차 미분
        grad_dot_v = torch.dot(flat_grads, v)
        hvp_batch = grad(grad_dot_v, model.parameters())
        hvp += torch.cat([h.flatten() for h in hvp_batch]).detach()
        n_batches += 1

    return hvp / n_batches


def inverse_hvp_lissa(
    model: torch.nn.Module,
    loss_fn,
    data_loader: torch.utils.data.DataLoader,
    v: torch.Tensor,
    damping: float = 0.01,
    num_iterations: int = 100,
    scale: float = 10.0,
    device: str = "cpu"
) -> torch.Tensor:
    """
    LiSSA (Linear time Stochastic Second-order Algorithm)로
    H^{-1} * v 근사

    반복식: h_{t+1} = v + (1 - damping) * h_t - HVP(h_t) / scale
    """
    ihvp_estimate = v.clone().to(device)

    for _ in range(num_iterations):
        hvp = hessian_vector_product(
            model, loss_fn, data_loader, ihvp_estimate, device
        )
        ihvp_estimate = v + (1 - damping) * ihvp_estimate - hvp / scale

    return ihvp_estimate / scale


def compute_influence_scores(
    model: torch.nn.Module,
    loss_fn,
    train_dataset,
    test_sample: Tuple[torch.Tensor, torch.Tensor],
    data_loader: torch.utils.data.DataLoader,
    damping: float = 0.01,
    device: str = "cpu"
) -> List[float]:
    """
    Influence Function 기반 TDA 점수 계산

    Args:
        model: 학습된 모델
        loss_fn: 손실 함수
        train_dataset: 학습 데이터
        test_sample: (x_test, y_test) 튜플
        data_loader: Hessian 근사용 데이터 로더
        damping: Hessian 정규화 계수
        device: 연산 장치

    Returns:
        각 학습 샘플의 영향력 점수 리스트
    """
    model.eval()
    x_test, y_test = test_sample

    # 테스트 샘플 그래디언트
    test_grad = compute_gradient(
        model, loss_fn, x_test.to(device), y_test.to(device)
    )

    # H^{-1} * test_grad 계산
    ihvp = inverse_hvp_lissa(
        model, loss_fn, data_loader, test_grad,
        damping=damping, device=device
    )

    # 각 학습 샘플에 대한 영향력
    scores = []
    for i in range(len(train_dataset)):
        x_train, y_train = train_dataset[i]
        train_grad = compute_gradient(
            model, loss_fn, x_train.to(device), y_train.to(device)
        )
        score = -torch.dot(ihvp, train_grad).item()
        scores.append(score)

    return scores

TracIn 구현

import torch
from pathlib import Path
from typing import List, Tuple, Optional


class TracInAttributor:
    """
    TracIn (Tracing with Gradient Descent) 기반 TDA

    체크포인트별 그래디언트 내적의 가중 합으로 영향력 측정
    """

    def __init__(
        self,
        model_factory,
        checkpoint_paths: List[str],
        learning_rates: List[float],
        device: str = "cpu"
    ):
        self.device = device
        self.learning_rates = learning_rates
        self.models = []

        for path in checkpoint_paths:
            model = model_factory()
            model.load_state_dict(torch.load(path, map_location=device))
            model.eval()
            self.models.append(model)

    def _gradient(
        self,
        model: torch.nn.Module,
        loss_fn,
        x: torch.Tensor,
        y: torch.Tensor
    ) -> torch.Tensor:
        model.zero_grad()
        out = model(x.unsqueeze(0).to(self.device))
        loss = loss_fn(out, y.unsqueeze(0).to(self.device))
        loss.backward()
        return torch.cat([
            p.grad.flatten() for p in model.parameters()
            if p.grad is not None
        ])

    def attribute(
        self,
        loss_fn,
        train_data,
        test_sample: Tuple[torch.Tensor, torch.Tensor],
        layers: Optional[List[str]] = None
    ) -> List[float]:
        """
        각 학습 샘플의 테스트 샘플에 대한 TracIn 점수 계산

        Args:
            loss_fn: 손실 함수
            train_data: 학습 데이터셋
            test_sample: (x_test, y_test)
            layers: 특정 레이어만 사용 (None이면 전체)

        Returns:
            학습 샘플별 영향력 점수
        """
        x_test, y_test = test_sample
        n = len(train_data)
        scores = [0.0] * n

        for ckpt_idx, model in enumerate(self.models):
            lr = self.learning_rates[ckpt_idx]
            test_grad = self._gradient(model, loss_fn, x_test, y_test)

            for i in range(n):
                x_i, y_i = train_data[i]
                train_grad = self._gradient(model, loss_fn, x_i, y_i)
                scores[i] += lr * torch.dot(test_grad, train_grad).item()

        return scores

    def top_influential(
        self,
        loss_fn,
        train_data,
        test_sample: Tuple[torch.Tensor, torch.Tensor],
        k: int = 10,
        mode: str = "proponents"
    ) -> List[Tuple[int, float]]:
        """
        가장 영향력 있는 학습 샘플 k개 반환

        Args:
            mode: "proponents" (긍정 영향) 또는 "opponents" (부정 영향)
        """
        scores = self.attribute(loss_fn, train_data, test_sample)
        indexed = list(enumerate(scores))

        if mode == "proponents":
            indexed.sort(key=lambda x: x[1], reverse=True)
        else:
            indexed.sort(key=lambda x: x[1])

        return indexed[:k]

TRAK 라이브러리 활용

# pip install traker[torch]
from trak import TRAKer
from trak.projectors import CudaProjector
import torch

def run_trak_attribution(
    model: torch.nn.Module,
    train_loader: torch.utils.data.DataLoader,
    test_loader: torch.utils.data.DataLoader,
    checkpoint_paths: list,
    save_dir: str = "./trak_results",
    proj_dim: int = 2048
):
    """
    TRAK 라이브러리를 사용한 대규모 TDA

    Args:
        model: 학습된 모델
        train_loader: 학습 데이터 로더
        test_loader: 테스트 데이터 로더
        checkpoint_paths: 체크포인트 경로 리스트
        save_dir: 결과 저장 경로
        proj_dim: 프로젝션 차원 (높을수록 정확, 느림)
    """
    # 파라미터 수 계산
    grad_dim = sum(p.numel() for p in model.parameters() if p.requires_grad)
    train_size = len(train_loader.dataset)

    traker = TRAKer(
        model=model,
        task="image_classification",  # 또는 "text_classification"
        train_set_size=train_size,
        projector=CudaProjector(
            grad_dim=grad_dim,
            proj_dim=proj_dim,
            seed=42,
            proj_type="rademacher",  # 또는 "normal"
        ),
        proj_dim=proj_dim,
        save_dir=save_dir,
    )

    # 각 체크포인트에서 학습 데이터 피처 계산
    for ckpt_idx, ckpt_path in enumerate(checkpoint_paths):
        traker.load_checkpoint(
            checkpoint=torch.load(ckpt_path),
            model_id=ckpt_idx
        )

        for batch_idx, (inputs, targets) in enumerate(train_loader):
            batch_start = batch_idx * train_loader.batch_size
            traker.featurize(
                batch=(inputs, targets),
                inds=torch.arange(
                    batch_start,
                    min(batch_start + len(inputs), train_size)
                ),
            )

    traker.finalize_features()

    # 테스트 데이터에 대한 귀속 점수
    for ckpt_idx, ckpt_path in enumerate(checkpoint_paths):
        traker.start_scoring_checkpoint(
            checkpoint=torch.load(ckpt_path),
            model_id=ckpt_idx,
            num_targets=len(test_loader.dataset),
        )

        for batch_idx, (inputs, targets) in enumerate(test_loader):
            traker.score(batch=(inputs, targets), num_samples=len(inputs))

    # 최종 점수: (num_test, num_train) 행렬
    scores = traker.finalize_scores()
    return scores


def analyze_attribution(scores, train_dataset, test_idx: int, top_k: int = 10):
    """귀속 결과 분석"""
    test_scores = scores[test_idx]  # (num_train,)

    # 상위 긍정 영향 (proponents)
    top_pos = torch.topk(torch.tensor(test_scores), top_k)
    print(f"Top {top_k} proponents:")
    for idx, score in zip(top_pos.indices, top_pos.values):
        print(f"  Train[{idx}]: score={score:.4f}")

    # 상위 부정 영향 (opponents)
    top_neg = torch.topk(-torch.tensor(test_scores), top_k)
    print(f"\nTop {top_k} opponents:")
    for idx, score in zip(top_neg.indices, -top_neg.values):
        print(f"  Train[{idx}]: score={score:.4f}")

데이터 디버깅 파이프라인

import numpy as np
from collections import Counter
from typing import Dict, List, Tuple


def detect_mislabeled_samples(
    attribution_scores: np.ndarray,
    val_predictions: np.ndarray,
    val_labels: np.ndarray,
    top_k: int = 50,
    threshold: float = 0.8
) -> List[Tuple[int, int, float]]:
    """
    TDA 기반 레이블 오류 탐지

    Args:
        attribution_scores: (num_val, num_train) 귀속 점수 행렬
        val_predictions: 검증셋 예측값
        val_labels: 검증셋 실제 레이블
        top_k: 각 오분류 샘플당 상위 k개 원인 추적
        threshold: 의심 빈도 임계값

    Returns:
        (학습 인덱스, 출현 빈도, 평균 영향력) 리스트
    """
    # 오분류 샘플 식별
    misclassified = np.where(val_predictions != val_labels)[0]
    print(f"오분류 샘플 수: {len(misclassified)}")

    suspect_counter = Counter()
    suspect_influence = {}

    for val_idx in misclassified:
        scores = attribution_scores[val_idx]
        # 가장 큰 긍정적 영향 = 오분류에 기여
        top_indices = np.argsort(scores)[-top_k:]

        for train_idx in top_indices:
            train_idx = int(train_idx)
            suspect_counter[train_idx] += 1
            if train_idx not in suspect_influence:
                suspect_influence[train_idx] = []
            suspect_influence[train_idx].append(scores[train_idx])

    # 빈도 기준 정렬
    results = []
    for train_idx, count in suspect_counter.most_common():
        avg_influence = np.mean(suspect_influence[train_idx])
        if count >= len(misclassified) * threshold:
            results.append((train_idx, count, avg_influence))

    print(f"의심 레이블 오류: {len(results)}개")
    return results


def data_quality_report(
    attribution_scores: np.ndarray,
    train_labels: np.ndarray
) -> Dict:
    """
    TDA 기반 학습 데이터 품질 리포트

    Returns:
        {
            "self_influence": 자기 영향력 분포,
            "outlier_indices": 이상치 인덱스,
            "class_confusion": 클래스 간 혼동 행렬
        }
    """
    n_train = attribution_scores.shape[1]

    # 자기 영향력 (self-influence)
    # 높은 자기 영향력 = 모델이 해당 샘플에 과도하게 의존
    self_influences = []
    for i in range(min(n_train, attribution_scores.shape[0])):
        self_influences.append(attribution_scores[i, i])

    self_influences = np.array(self_influences)
    mean_si = np.mean(self_influences)
    std_si = np.std(self_influences)

    # 이상치: 자기 영향력이 비정상적으로 높은 샘플
    outlier_threshold = mean_si + 3 * std_si
    outliers = np.where(self_influences > outlier_threshold)[0]

    return {
        "self_influence_mean": float(mean_si),
        "self_influence_std": float(std_si),
        "outlier_indices": outliers.tolist(),
        "n_outliers": len(outliers),
    }

LLM 사전학습 귀속

Fact Tracing

목표: LLM이 "서울은 한국의 수도이다"라고 생성할 때
      어떤 학습 문서가 이 지식에 기여했는가?

TrackStar 접근 (Chang et al., ICLR 2025):
  1. 테스트 쿼리: "한국의 수도는?" -> "서울"
  2. 마지막 토큰의 그래디언트 계산
  3. 학습 코퍼스 각 문서의 그래디언트와 비교
  4. 상위 "proponents" = 가장 관련 있는 학습 문서

결과 예시 (Gemma 8B, C4 코퍼스):
  쿼리: "Albert Einstein was born in"
  Top proponents:
    1. Wikipedia 기사: 아인슈타인 전기 (score: 0.92)
    2. 물리학 교과서 발췌 (score: 0.71)
    3. 노벨상 수상자 목록 (score: 0.58)

주요 발견:
  - 모델 크기 증가 -> 귀속이 factual entailment와 더 일치
  - 2B vs 8B: 8B가 관련 문서를 더 정확히 가리킴
  - 학습 토큰 수 증가 -> 영향력이 소수 문서에 집중

저작권 추적 응용

시나리오: LLM이 특정 작가 스타일의 텍스트 생성
  -> TDA로 원본 저작물 기여도 측정
  -> 기여도에 비례한 보상 산정

기술적 파이프라인:
  1. 생성 텍스트에 대한 귀속 점수 계산
  2. 학습 코퍼스의 출처(source) 메타데이터와 매핑
  3. 출처별 기여도 집계
  4. 법적/경제적 판단의 근거 제공

한계:
  - "영향"과 "복제"는 다른 개념
  - 기여도의 법적 해석은 미확정
  - 계산 비용이 실시간 서비스에 부적합

평가 지표

1. Linear Datamodeling Score (LDS)
   정의: 부분집합 학습 모델의 실제 예측과 TDA 점수의 선형 상관
   방법:
     - T개의 무작위 부분집합 S_1, ..., S_T 샘플링
     - 각 S_t로 모델 학습 -> f_{S_t}(x_test) 측정
     - TDA 예측: y_hat_t = sum_{i in S_t} alpha_i
     - LDS = Spearman(y_hat, y_actual)

   비용: T회 전체 재학습 필요 (벤치마크용)
   기준값: CIFAR-10에서 TRAK ~0.70, IF ~0.58

2. Leave-One-Out (LOO) 상관관계
   정의: 실제 LOO 결과와 TDA 추정값의 상관
   비용: n회 재학습 -> 소규모 데이터셋에서만 가능

3. Mislabel Detection Rate
   정의: 의도적으로 삽입한 레이블 오류의 탐지율
   방법:
     - 학습 데이터의 k%에 랜덤 레이블 부여
     - TDA로 의심 샘플 선별
     - Precision@k% 측정

4. Counterfactual Evaluation
   정의: TDA 상위 샘플 제거 후 실제 예측 변화
   - 영향력 높은 샘플 제거 -> 예측이 크게 변하면 좋은 TDA

실세계 응용

데이터 큐레이션

목표: 학습 데이터에서 품질이 낮은 샘플 자동 제거

파이프라인:
  1. 전체 학습 데이터의 TDA 점수 계산
  2. 검증 데이터 성능에 부정적 영향(opponents) 식별
  3. 상위 k% 부정 영향 샘플 제거
  4. 정제된 데이터로 재학습

결과 (TRAK 논문):
  CIFAR-10: 상위 10% 유해 데이터 제거 -> 정확도 +0.8%
  ImageNet: 상위 5% 제거 -> 정확도 +0.3%

AI 안전

유해 출력 원인 추적:
  - LLM의 유해/편향 출력에 대해 TDA 수행
  - 원인 학습 데이터 식별
  - 타겟 제거 또는 카운터 데이터 추가

기계적 망각 (Machine Unlearning)과의 연결:
  - TDA로 제거 대상 데이터의 영향력 측정
  - 영향력 기반 파라미터 업데이트로 "망각"
  - 완전 재학습 없이 특정 데이터의 효과 제거

한계 및 주의사항

1. 근사 오차
   - 모든 실용적 방법은 LOO의 "근사"
   - 비볼록 손실 함수에서 이론적 보장 약화
   - 근사 오차가 대규모 모델에서 체계적으로 누적
   - 해결: 앙상블 (TRAK), 보정 (TrackStar)

2. 상호작용 효과 (Interaction Effects)
   - TDA는 개별 샘플의 "한계 기여도" 측정
   - 데이터 간 시너지/상쇄 효과 포착 어려움
   - 예: z_1, z_2 각각은 영향 없지만 함께 있으면 큰 영향
   - 해결: 그룹 단위 TDA (AirRep), Data Shapley

3. 계산 비용
   - LLM 규모에서도 여전히 비용 높음 (GPU-days)
   - 학습 코퍼스 전체 순회 필요
   - 실시간 서비스에 부적합
   - 해결: 사전 계산 + 인덱싱, 랜덤 프로젝션

4. 평가의 어려움
   - LDS 계산 자체가 비용 높음 (T회 재학습)
   - 대규모 모델에서는 LDS 계산 불가
   - 프록시 평가(mislabel detection)의 한계
   - 해결: 합성 벤치마크, 소규모 모델에서 검증 후 확장

5. 인과적 해석의 한계
   - "상관" vs "인과": 높은 TDA 점수가 인과적 영향을 보장하지 않음
   - 학습 순서, 배치 구성 등에 따라 영향이 달라질 수 있음
   - 해결: 반복 실험, counterfactual 검증

관련 연구 흐름

Cook's Distance (통계학, 1977)
    |
    +-- Influence Functions (Koh & Liang, ICML 2017)
    |       |
    |       +-- RelatIF (Barshan et al., 2020)
    |       +-- EK-FAC Influence (Grosse et al., 2023)
    |       +-- LoGra (Choe et al., NeurIPS 2024)
    |
    +-- TracIn (Pruthi et al., NeurIPS 2020)
    |       |
    |       +-- Hydra (Chen et al., 2021)
    |
    +-- Datamodels (Ilyas et al., ICML 2022)
    |       |
    |       +-- TRAK (Park et al., ICML 2023)
    |               |
    |               +-- D-TRAK (Zheng et al., 2024, Diffusion 확장)
    |
    +-- Data Shapley (Ghorbani & Zou, ICML 2019)
    |       |
    |       +-- Beta Shapley (Kwon & Zou, AISTATS 2022)
    |       +-- Data Banzhaf (Wang & Jia, ICML 2023)
    |
    +-- TrackStar (Chang et al., ICLR 2025)
    |       |
    |       +-- LLM 사전학습 규모의 TDA
    |
    +-- AirRep (Sun et al., NeurIPS 2025)
    |       |
    |       +-- 학습 가능 인코더 기반 TDA
    |
    +-- Copyright/Legal Applications (2024~)
            |
            +-- 데이터 보상 메커니즘
            +-- AI 규제와 TDA의 접점

참고 자료

핵심 논문

  1. Koh, P.W. & Liang, P. (2017). Understanding Black-box Predictions via Influence Functions. ICML 2017.
  2. Pruthi, G. et al. (2020). Estimating Training Data Influence by Tracing Gradient Descent. NeurIPS 2020.
  3. Ilyas, A. et al. (2022). Datamodels: Predicting Predictions from Training Data. ICML 2022.
  4. Park, S.M. et al. (2023). TRAK: Attributing Model Behavior at Scale. ICML 2023.

확장 논문

  1. Grosse, R. et al. (2023). Studying Large Language Model Generalization with Influence Functions. arXiv:2308.03296.
  2. Choe, S.K. et al. (2024). What is Your Data Worth to GPT? LLM-Scale Data Valuation with Influence Functions. NeurIPS 2024.
  3. Chang, T.A. et al. (2025). Scalable Influence and Fact Tracing for Large Language Model Pretraining. ICLR 2025.
  4. Sun, X. et al. (2025). AirRep: Enhancing Training Data Attribution with Representational Optimization. NeurIPS 2025.

관련 개념