개요

38편과 39편은 모델을 기기에 올리는 이야기였다. 어떤 칩에 올리고, 어떻게 소수점을 지워내는지.

그래서 올렸다고 하자. 그럼 끝일까. 자료가 여기서 좀 얄궂은 숫자를 보여준다. 학습할 때 검증 정확도가 97%였던 모델을 현장에 내놨더니 68%가 됐다.

모델은 하나도 안 바뀌었다. 바뀐 건 들어오는 데이터다. 학습할 땐 깨끗한 사진으로 배웠는데, 실제 현장의 카메라는 어둡고 흐리고 노이즈가 낀다.

이번 글이 답할 질문 이미 배포한 모델을, 정답 라벨도 없고 다시 학습할 시간도 없는 상태에서, 어떻게 그 자리에서 고쳐 쓰는가.

교육 과정 자료는 대외비라 원본 자료는 싣지 않는다.


1. 분포 이동 — 모델은 그대로인데 세상이 달라진다

분포 이동(Distribution Shift) 이라고 부른다. AI가 실제로 쓰이는 순간, 학습 데이터에서 겪어보지 못한 낯선 데이터를 만나는 현상이다.

학습 분포와 테스트 분포가 어긋난다

여기서 중요한 건 모델이 틀린 게 아니라는 점이다. 모델은 자기가 배운 대로 정확히 동작하고 있다. 배운 세상이 눈앞의 세상과 다를 뿐이다.

더 쉬운 비유로

서울에서만 운전을 배운 사람이 눈 쌓인 산길에 처음 올라간 것이다.

운전을 못 하는 게 아니다. 핸들 조작도 정확하고 신호도 잘 본다. 그런데 노면이 다르다. 여기서 필요한 건 운전을 처음부터 다시 배우는 것이 아니라, 지금 노면에 맞춰 브레이크 감각을 다시 잡는 것이다.

39편까지의 이야기는 전부 “모델을 어떻게 다듬는가” 였다. 이 편은 다르다. 모델이 아니라 상황이 문제다.

학습을 아무리 잘해도 못 막는 종류의 문제다. 세상의 모든 경우를 미리 학습 데이터에 담는 건 불가능하니까.


2. 라벨이 없다 — 엔트로피라는 우회로

그럼 현장 데이터로 다시 학습시키면 되지 않나. 안 된다. 정답 라벨이 없다.

25편에서 본 교차 엔트로피 손실을 떠올려보자. “모델이 뭐라고 답했는지”와 “정답이 뭔지”를 비교해서 그 차이를 줄이는 방식이었다. 정답이 있어야 성립한다.

현장에서 카메라가 찍어 보내는 사진에는 정답표가 안 붙어 있다. 사람이 하나하나 붙여줄 수도 없다.

그래서 정답 대신 쓰는 게 엔트로피다

엔트로피(entropy) 는 “얼마나 어정쩡한가”를 재는 숫자다.

$$ H(p) = -\sum_{i} p_i \log p_i $$

p_i는 모델이 각 정답 후보에 매긴 확률이다. 이 값은 이렇게 움직인다.

모델의 예측 엔트로피 해석
고양이 99%, 나머지 1% 낮다 확신하고 있다
고양이 40%, 개 35%, 새 25% 높다 어정쩡하다

정답이 뭔지는 몰라도, 모델이 헷갈려하는지 아닌지는 알 수 있다. 라벨 없이 구할 수 있는 유일한 신호다.

TTA 기법들이 전부 여기서 출발한다. 엔트로피를 손실 함수로 놓고, 그걸 줄이는 방향으로 모델을 민다. 확신하는 쪽으로 밀면 대체로 정답 쪽으로 간다는 가정이다.

더 쉬운 비유로

시험지 채점을 못 해주는 대신, “너 이거 확실해?” 만 계속 물어보는 것이다.

답이 맞는지는 못 알려준다. 대신 우물쭈물하는 문제가 있으면 “좀 더 자신 있게 답할 수 있는 상태가 되어봐라” 라고만 시킨다. 답을 아는 사람이 없어도 가능한 지도다.

물론 완벽한 방법은 아니다. 틀린 답을 확신하는 경우도 있으니까. 이 허점을 어떻게 막는지가 뒤에 나온다.

라벨이 없으면 정답률을 못 잰다. 하지만 망설임은 잴 수 있다. TTA는 그 하나만 붙잡고 간다.

신호는 하나인데, 손잡이는 모델마다 다르다

여기서 TTA 기법이 두 갈래로 갈린다. 엔트로피라는 신호는 똑같이 쓰는데, 그 신호로 무엇을 미느냐가 모델 구조에 따라 달라지기 때문이다.

갈래 대상 모델 미는 손잡이 이번 글에서 볼 기법
CNN 계열 배치 정규화가 들어간 합성곱 모델 배치 정규화의 통계와 조절값 TENT, SAR
비전언어 계열 CLIP처럼 문장과 이미지를 맞춰보는 모델 텍스트·이미지 프롬프트 TPT, PromptAlign

갈래가 갈리는 이유는 단순하다. CLIP에는 배치 정규화 계층이 없고, 합성곱 분류 모델에는 프롬프트가 없다. 각자 자기 모델에서 제일 작게 건드릴 수 있는 부분을 찾아간 결과다.

어느 쪽이든 원칙은 같다. 모델 전체가 아니라, 그 구조에서 제일 만만한 손잡이 하나만 돌린다.


3. CNN 계열 ① TENT — 배치 정규화의 눈금만 다시 맞춘다

먼저 배치 정규화가 들어간 합성곱 모델에 쓰는 기법부터다. 23편에서 본 ResNet 계열이 전부 여기에 해당한다.

가장 기본이 되는 기법이 TENT다. 손대는 곳이 딱 하나, 23편과 39편에서 계속 나온 배치 정규화 계층이다.

배치 정규화가 하는 일을 다시 보자.

$$ BN(x) = \gamma \cdot \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} + \beta $$

여기서 μσ데이터의 통계고, γβ학습으로 배운 조절값이다. TENT는 이 둘을 각각 다르게 다룬다.

1단계 — 평균·분산을 다시 잰다. 원래 저장돼 있던 μ, σ²는 학습 데이터 기준이다. 이걸 버리고 지금 들어온 테스트 데이터로 다시 계산한다. 학습이 아니라 그냥 다시 재는 것이라 즉시 된다.

2단계 — 조절값만 미세 조정한다. γβ엔트로피를 손실로 삼아 역전파로 살짝 움직인다. 나머지 가중치는 전부 그대로 둔다.

업데이트하는 범위 비교

37편의 LoRA와 발상이 비슷하다. 전부 안 건드리고 필요한 데만 건드린다. 다만 LoRA는 어댑터를 새로 붙였고, TENT는 이미 있던 파라미터 중 제일 작은 두 개만 쓴다.

더 쉬운 비유로

카메라를 새로 사는 게 아니라, 화이트밸런스만 다시 잡는 것이다.

렌즈도 센서도 그대로다. 조명이 형광등에서 백열등으로 바뀌었으니 색 기준선만 다시 맞춘다. 5초면 되고, 사진 찍는 실력은 하나도 안 바뀐다.

모델이 무엇을 아는지는 안 건드린다. 어떤 눈금으로 보는지만 다시 맞춘다.


4. CNN 계열 ② SAR — 확신 있는 것만 듣는다

같은 CNN 계열이고, 손대는 곳도 TENT와 똑같이 배치 정규화다. 달라지는 건 누구 말을 듣느냐다.

TENT는 잘 되는데 문제가 하나 있다. 불안정하다.

들어오는 테스트 데이터가 다 멀쩡하지는 않다. 완전히 뭉개진 사진, 아예 다른 게 찍힌 사진이 섞여 들어온다. 그런 샘플은 모델이 극도로 헷갈려하니 엔트로피가 매우 높고, 그래서 역전파 때 큰 그래디언트를 만든다.

그 한 장 때문에 모델 전체가 이상한 방향으로 끌려간다. 배포 중인 모델이 실시간으로 망가지는 것이라 꽤 위험하다.

SAR는 여기에 두 가지 안전장치를 건다.

1 — 샘플을 고른다. 들어온 것 중 엔트로피가 낮은 샘플만 골라서 업데이트에 쓴다. 모델이 이미 어느 정도 확신하는 것만 반영하고, 도저히 모르겠는 건 그냥 넘긴다.

2 — 손실을 평탄하게 만든다. 손실이 조금만 움직여도 결과가 확 달라지는 뾰족한 지점 말고, 주변까지 다 같이 낮은 완만한 지점을 찾아간다. 25편에서 손실 지형(loss landscape) 이야기가 나왔는데, 그 지형을 평평한 쪽으로 골라 앉는 것이다.

결과는 TENT보다 학습이 안정적이고, 험한 테스트 환경에서도 성능이 유지된다.

더 쉬운 비유로

설문조사에서 “잘 모르겠다”고 답한 사람의 표를 그냥 빼버리는 것이다.

억지로 세면 노이즈만 커진다. 확실히 의견이 있는 사람 표만 세도 방향은 충분히 나온다. SAR가 하는 게 그거다.

TENT가 가능성을 보여줬다면, SAR는 그걸 현장에 내놓을 수 있게 만들었다.


5. 비전언어 계열 TPT와 PromptAlign — 이번엔 프롬프트를 고친다

여기서 갈래가 바뀐다. 앞의 둘은 합성곱 모델용이었고, 이제 27편에서 본 CLIP 같은 비전언어 모델 차례다.

CLIP은 이미지와 문장을 같은 공간에 놓고 비교하는 모델이었다. 분류를 할 때 "a photo of a cat" 같은 문장을 후보로 던져놓고 어느 문장이 이미지와 제일 가까운지 고른다. 배치 정규화 계층이 아예 없으니 앞의 방식을 그대로 가져올 수가 없다.

대신 여기엔 다른 손잡이가 있다. 프롬프트다. 29편에서 본 그 프롬프트 튜닝을, 학습 때가 아니라 테스트 때 하는 것이다.

TPT — 한 장을 여러 장처럼 본다

문제가 하나 있다. 테스트 시점에 이미지는 딱 한 장 들어온다. 한 장으로 뭘 배우나.

TPT의 답은 이렇다.

  1. 그 한 장을 여러 방식으로 증강한다. 돌리고, 자르고, 밝기를 바꾸고 (25편의 데이터 증강이 여기서 다시 나온다)
  2. 증강본들의 예측을 다 뽑아보고, 엔트로피가 가장 낮은 6개만 남긴다
  3. 그 6개의 평균 엔트로피를 손실로 삼아 텍스트 프롬프트를 갱신한다

발상이 좋았다. 같은 물체면 어떻게 변형해도 답이 같아야 한다. 답이 흔들린다면 프롬프트가 그 이미지에 안 맞는 것이다. 그러니 “여러 각도에서 봐도 일관되게 답이 나오도록” 프롬프트를 미는 것이다.

엔트로피 낮은 6개만 쓰는 것도 SAR와 같은 이유다. 증강하다 보면 물체가 잘려나가서 알아볼 수 없게 된 장면도 나오는데, 그런 걸 반영하면 안 되니까.

PromptAlign — 기준점을 하나 더 준다

TPT에는 여전히 허점이 있다. 엔트로피만 보고 움직인다는 것. 확신만 세지면 되니까, 엉뚱한 쪽으로 확신을 굳혀도 손실은 줄어든다.

PromptAlign은 여기에 기준점을 하나 더 준다. 학습에 썼던 데이터의 통계(계층별 평균·분산)를 미리 저장해둔다. 그리고 테스트 데이터를 넣었을 때 나오는 통계가 그 저장해둔 값과 가까워지도록 맞춰나간다.

  • 엔트로피 손실 — “헷갈리지 말아라”
  • 정렬 손실 — “학습 때 보던 모습에서 너무 벗어나지도 말아라”

두 손실을 같이 쓰고, 텍스트 프롬프트뿐 아니라 이미지 쪽 프롬프트까지 같이 갱신한다.

네 기법의 계보

네 개를 나란히 놓고 보니 흐름이 보였다. TENT → SAR는 “확신만 좇다 흔들리는 걸” 막았고, TPT → PromptAlign도 똑같이 “확신만 좇는 걸” 기준점으로 잡아줬다. 이름과 대상만 다르지 고민이 같다.

라벨 없이 배우는 방법은 결국 하나뿐이라, 다들 같은 함정을 밟고 같은 방식으로 빠져나온다.


정리

  • 분포 이동 — 학습 때 본 데이터와 실제로 들어오는 데이터의 통계가 다른 현상. 모델이 틀린 게 아니라 세상이 다른 것이다. 자료 예시로 97%가 68%까지 떨어졌다
  • TTA(테스트 타임 도메인 적응) — 다시 학습하지 않고, 테스트 데이터가 들어오는 그 순간 모델 일부만 즉시 조정한다
  • 정답 라벨이 없으니 엔트로피를 손실로 쓴다. 정답률은 못 재도 망설임은 잴 수 있다
  • 신호는 같아도 손잡이는 모델 구조마다 다르다. 배치 정규화가 있는 CNN 계열은 그 계층을, 그게 없는 비전언어 계열프롬프트를 민다
  • TENT (CNN 계열) — 배치 정규화의 평균·분산을 테스트 데이터로 재계산하고, γ·β만 엔트로피로 미세 조정. 눈금만 다시 맞추는 것
  • SAR (CNN 계열) — TENT의 불안정을 보완. 엔트로피 낮은 샘플만 골라 쓰고, 손실 지형을 평탄한 쪽으로 잡는다
  • TPT (비전언어 계열) — 테스트 이미지 한 장을 여러 번 증강해 엔트로피 낮은 6개를 고르고, 그 평균 엔트로피로 텍스트 프롬프트를 갱신
  • PromptAlign (비전언어 계열) — 저장해둔 학습 통계에 계층별로 정렬하는 손실을 추가. 텍스트와 이미지 프롬프트를 함께 갱신

이번 편이 앞의 편들과 다른 점

35편부터 39편까지는 전부 배포 전의 이야기였다. 줄이고, 깎고, 튜닝하고, 소수점을 지우고, 칩에 올리고.

이 편은 배포 후다. 그래서 제약이 완전히 달랐다.

배포 전 배포 후 (TTA)
라벨이 있다 라벨이 없다
시간을 들일 수 있다 지금 당장 답해야 한다
실패하면 다시 하면 된다 서비스 중이라 망가지면 안 된다

SAR가 왜 그렇게 조심스러운 장치를 두 개나 달았는지, 이 표를 보고 나서야 이해가 됐다.

배포 전에는 잘 만드는 게 목표고, 배포 후에는 안 망가지는 게 목표다.


참고 자료

한줄 평

정답을 모르는 채로 가르치는 방법이 있다는 게 신기했는데, 그 대가를 다들 감수하며 쓰고있다는 게 더 재밌었다!