2026년 7월 30일, Transformers는 T5에 PyTorch의 scaled dot-product attention (SDPA) 기능을 활성화했습니다. 부수적인 결과로 UMT5의 디코더가 미래 토큰(future tokens)에 접근할 수 있게 되었습니다. 이는 학습 중에 모델이 예측해야 할 정답을 엿보는 것과 같았습니다. 시스템은 다운되지 않았고, 이 버그는 거의 두 달 동안 main 브랜치에 남아 있었습니다.
나중에 해당 커밋들을 재현했을 때, CPU에서 실행되는 작은 UMT5 모델이 모든 커밋에서 이를 감지했습니다. 본 게시물은 그 모델과 그것을 중심으로 구축된 테스트들에 관한 내용입니다.
Transformers는 750개 이상의 모델 유형을 지원하며, 테스트 스위트 규모가 매우 큽니다: main 브랜치에서 88,000개 이상의 CPU 테스트와 일일 실행으로 200,000개 이상의 GPU 테스트를 진행합니다. 모델 테스트는 일부에 불과합니다. 저희는 파이프라인(pipelines), 학습(training), 분산 실행(distributed execution), 양자화(quantization) 및 어텐션 커널(attention kernels)도 테스트합니다.
통합 테스트(integration tests)는 실제 체크포인트(checkpoints)를 로드하고 실제 하드웨어에서 모델의 API를 사용해봅니다. 이 모든 것을 매 PR(Pull Request)마다 실행하려면 하루 종일 많은 GPU 자원을 점유해야 하므로 실용적이지 않습니다. 스케줄링된 실행이 회귀(regression)를 발견할 때쯤이면 이미 main 브랜치에 있을 수도 있습니다.
저희의 접근 방식은 모델 자체를 축소하는 것입니다. 저희는 **피처(fixture)**라는 것을 구축합니다: 이는 실제 체크포인트의 설정으로 만들어졌지만, 레이어 수는 적고 좁지만 모든 종류의 레이어를 포함하며, 토크나이저와 프로세서 파일은 변경되지 않은 작은 모델입니다. 이 피처는 한 번 게시된 후 재사용됩니다. 저희는 이를 저렴한 CPU 러너에서 '빠른 통합 테스트(fast integration tests)'에 사용합니다. 저희의 CPU 연구에서 실험적인 UMT5 피처는 66 MB의 가중치(weights)를 사용했고, 원본 체크포인트는 1,227 MB였습니다.
이 방식은 매우 큰 모델에도 적용됩니다: 일부 모델은 표준 GPU 러너에 맞지 않지만, 그 피처들은 CPU에서 실행될 수 있습니다.
모델 통합 담당자들은 이미 작은 테스트 모델(Transformers의 tiny-random-* 체크포인트)을 구축하고 있습니다. 저희는 공통적인 레시피와 단순히 모델을 로드하고 순전파(forward pass)를 실행하는 것을 넘어선 검사를 원했습니다. UMT5 버그는 순전파만으로는 아무 문제 없이 통과했을 것입니다.
피처가 전체 통합 테스트를 대체하지는 못하지만, PR 단계에서 main 브랜치에 도달하기 전에 버그를 잡을 기회를 제공합니다.
transformers-mic는 이러한 테스트를 패키징하기 위한 제안된 표준입니다. 모델 통합 컨트랙트(Model Integration Contract, MIC)는 세 부분으로 구성됩니다:
- 피처 (fixture): 위에서 설명한 축소된 모델로, 한 번 게시되고 고정됩니다.
- 사용 경로 (usage path): 텍스트 생성이나 학습 단계 실행 등 사용자가 모델을 사용하는 방법을 보여주는 실행 가능한 Markdown 예시입니다.
- 베이스라인 (baselines): 해당 예시를 실행했을 때 기록되는 출력물이며, 사람이 검토합니다.
컨트랙트는 피처에서 사용 경로를 실행했을 때 여전히 베이스라인을 생성하는 경우에 유효합니다.
컨트랙트는 단일 체크포인트가 아닌 아키텍처와 사용 경로를 다룹니다. 호환되는 체크포인트들은 피처를 공유할 수 있지만, 각각은 자체적인 예상 결과를 유지합니다. 우리는 이를 huggingface-mic에 게시합니다.
예를 들어, SmolLM 컨트랙트는 "The capital of France is"와 같은 프롬프트로부터 생성하며, 그 토큰 ID를 기록된 답변과 비교합니다. 모델과 토크나이저를 로드한 후, 생성 코드는 하나의 프롬프트로 간소화됩니다:
inputs = tokenizer("The capital of France is", return_tensors="pt")
outputs = model.generate(**inputs, max_new_tokens=4, do_sample=False)
new_tokens = outputs[:, inputs["input_ids"].shape[1]:]
...
또한 학습 손실(training loss)을 비교하고, 그래디언트가 유한한지 확인하며, 옵티마이저 단계가 가중치를 변경하는지 검증합니다. 전체 내용은 usage.md를 참조하십시오.
허브(Hub)의 플릿 데이터셋(fleet dataset)은 각 MIC를 고정된 리비전과 함께 핀하고, 베이스라인을 기록하는 데 사용된 패키지 버전도 함께 저장합니다. 각 CI 실행은 자신이 사용한 플릿 리비전을 기록하므로 나중에 재현할 수 있습니다.
PR에서는 패치가 변경하는 파일들을 기반으로 MIC를 선택합니다.
우리는 트랜스포머(Transformers) 커밋 5개월 동안 고정된 MIC를 재실행했습니다. 작은 UMT5 피처는 2026년 7월 30일에 도입되어 9월 28일에 수정될 때까지의 회귀를 감지했습니다. 레이블 로그 확률은 검토된 베이스라인과 1.22만큼, 학습 손실(training loss)은 약 0.20만큼 차이가 있었습니다.
중요한 세부 사항이 있었습니다: 컨트랙트는 기본 어텐션 경로인 SDPA를 사용했습니다. 이저(eager) 어텐션 변형만 실행해서는 버그를 놓쳤습니다. 피처(fixture)는 실제 체크포인트와 동일한 코드를 거칠 때만 도움이 됩니다.
이후 저희는 Transformers의 CI(지속적 통합)에 있는 프로브 브랜치에서 해당 수정 사항을 되돌렸습니다. 검사는 동일한 차이점과 함께 실패했으며, 선택된 T5 컨트랙트의 러너 단계는 설정 시간을 제외하고 CPU에서 13.4초가 소요되었습니다.
리플레이 결과와 CI 데모에는 측정값과 재현 세부 정보가 포함되어 있습니다.
첫 번째 레시피는 간단했습니다: 차원을 더 작게 만들고 레이어 수를 줄이는 것이었습니다. 이것만으로는 혼합 아키텍처(mixed architectures)에 충분하지 않았습니다. 두 개의 레이어를 유지하더라도 둘 다 슬라이딩 어텐션(sliding attention)을 사용하고 풀-어텐션(full-attention) 레이어가 사라진다면 소용이 없습니다.
이제 이 레시피는 네 단계로 구성되어 있습니다:
설정 축소(Shrink the configuration). 실제 체크포인트에서 시작하여 숨겨진 크기(hidden sizes), 어텐션 헤드(attention heads), 깊이(depth)를 줄입니다. 슬라이딩 및 풀-어텐션의 혼합 또는 Dense와 MoE 레이어를 포함한 다양한 유형의 레이어는 유지합니다. 일부 아키텍처는 구성 요소가 호환되도록 추가 규칙이 필요합니다. 또한 모델 자체의 Transformers 테스트, 즉 test_modeling_<model>.py에 있는 ModelTester도 살펴봅니다.
이미 수동으로 작은 설정을 선택하므로, 일반 규칙이 이름으로 알지 못하는 모든 너비에 대해 그 크기를 가져옵니다.전처리 과정은 변경하지 않습니다. 어휘(vocabulary), 특수 토큰(special tokens) 및 입력 차원(input dimensions)을 보존하고, 토크나이저(tokenizer)와 프로세서(processor) 파일을 바이트 단위로 복사합니다. 로딩과 전처리는 우리가 테스트하려는 부분 중 일부입니다.가중치 구축 및 검증. 시드된 랜덤 가중치를 사용해보고 입력을 변경하여 모델이 응답하는지 확인합니다. 만약 그렇지 않다면, 컨트랙트의 작은 배치 예제를 사용하여 학습시켜 봅니다. 저장된 모델을 다시 로드하고 출력(outputs), 손실(loss), 기울기(gradients)가 유한한지 확인합니다. 실패한 구축은 거부됩니다.동결 및 기록. 승인된 가중치를 저장하고 알려진 좋은 Transformers 빌드를 기반으로 재현 가능한 출력을 측정합니다. 지원되는 각 플랫폼과 정밀도(precision)에 대한 기준선(baselines)을 검토한 후, 고정된 스냅샷(pinned snapshot)을 게시합니다. CI는 이를 재사용하며, 모든 PR마다 피처(fixture)를 다시 구축하지 않습니다.
또한 원래 가중치 파일 형식도 유지합니다. 그렇지 않으면 사용자가 실제 체크포인트(checkpoint)를 로드할 때 실행되는 변환 코드를 건너뛰게 됩니다. 전체 레시피에는 더 자세한 내용이 있습니다.
Llama 4 Scout 축소 보고서(shrink report)는 이것이 대규모 모델에서 어떻게 보이는지 보여줍니다. 1086억 개의 파라미터가 4470만 개로 줄어듭니다. 비전 스택(vision stack)은 34개 레이어에서 2개로, 언어 스택(language stack)은 48개에서 4개로 줄어들지만, 검사된 레이어 종류와 MoE 라우팅 스타일은 유지됩니다.
당사의 CLI인 tmic는 컨트랙트를 생성하고 피처를 구축합니다. 새로운 모델의 경우, LLM이 사용 코드(usage code)와 매니페스트(manifest) 초안을 작성하며, CPU 및 GPU 실행은 후보 기준선(candidate baselines)을 측정합니다. LLM이 초안을 작성할 뿐이며 승인하지는 않습니다. 변경된 기대치(expectations)는 인간의 검토가 필요합니다.
사용자의 머신에서 이를 시도하려면, org/model 대신 소스 체크포인트를 사용하십시오:
pip install "transformers-mic[runtime]" "hf-doc-builder @ git+https://github.com/huggingface/doc-builder.git"
hf auth login
tmic run org/model --local-only --fixtures-only --no-history --bill-to ''
이 과정은 컨트랙트를 초안 작성하고, 피처(fixture)를 구축하며, 사용자님의 머신에 기준선(baseline)을 기록합니다. 각 단계를 검토하도록 요청한 후, 아무것도 업로드하기 전에 멈춥니다.
새로운 모델의 경우, 초안은 추론 제공자(Inference Providers)를 통해 LLM으로부터 생성되며, 사용자 본인의 계정(--bill-to '')으로 청구됩니다. 개별 단계는 CLI 문서에 설명되어 있습니다.
저희는 에이전트(agents)를 사용하여 모델군 전반에 걸쳐 MIC(Model Integration Contracts)를 구축했습니다. 엣지 케이스(edge case)에 직면했을 때, 모델 전문가들의 도움을 받아 특정 피처가 아닌 레시피 자체를 수정했습니다. 공개된 모델과 남아있는 격차는 커버리지 공간(coverage space)에 있습니다.
무작위 가중치(random weights)를 사용했을 때, 저희의 Whisper 피처는 오디오 변화에 거의 반응하지 않았습니다. 실행은 되었지만, 이는 오디오 경로(audio path)에 대한 좋지 않은 테스트였습니다.
그래서 저희는 "빨간색(red)" 및 "녹색(green)"과 같은 단어와 쌍을 이루는 몇 가지 음조(tones)로 이를 학습시켰습니다. 저희가 음성 인식(speech recognition)을 가르치려 한 것이 아니라, 오디오 변화를 출력에서 눈에 띄게 만드는 것이 목적이었습니다. 가중치 초기화 연구(weight-initialization study)에서 무작위 Whisper 피처는 주입된 24개 결함 중 18개를 포착했습니다. 과적합(overfit) 피처는 24개 전체를 포착했습니다.
이를 통해 가중치를 구축하는 두 가지 방법을 얻게 되었습니다:
- 무작위 가중치와 고정된 시드(seed)로 시작하는 방법.
- "프랑스의 수도는" => "파리(Paris)"와 같은 몇 가지 예시를 통해 과적합시키는 방법.
Whisper의 결과는 어느 쪽이 더 좋은지 결정하지 못합니다. 그것들은 합성 결함(synthetic faults)이었으며, 저희는 과적합 버전만 포착하는 실제 회귀(regression)를 발견하지 못했습니다. 두 버전 모두 실제 Whisper 체크포인트가 노출한 보조 디코딩 버그(assisted-decoding bug)를 놓쳤습니다.
따라서 검사를 통과할 때는 무작위 가중치를 유지하고, 더 나은 민감도(sensitivity)나 읽기 쉬운 답변이 필요할 때만 과적합을 사용합니다. 학습에는 몇 초밖에 걸리지 않지만, 수렴에 실패할 수 있는 또 하나의 단계이며 관리해야 할 또 다른 요소입니다. 비교 자료에는 두 가지 모두의 결과가 있습니다.
2026년 11월 1일 기준으로, Transformers CI의 MIC 작업은 PR(Pull Request)을 차단하지 않고 실패를 보고합니다. 이것이 차단해야 하는지 여부는 저희가 아직 측정하지 못한 것들에 달려 있습니다:
- 리플레이(replays)뿐만 아니라 실제 PR에서 몇 개의 버그를 포착하는가?
- 얼마나 자주 저희에게 오탐지 경보(false alarms)를 추적하도록 만드나?
- 기준선 검토(baseline reviews)에 얼마나 많은 작업 시간이 필요한가?
또한 Whisper 보조 디코딩과 같은 버그가 실제 가중치에서만 나타나는지, 또는 과적합(overfitting)이 무작위 가중치가 놓치는 실제 버그를 잡아내는지 알 수 없습니다.
모델 계열 및 사용자들이 사용하는 API 전반에 걸쳐 커버리지(Coverage)는 여전히 부분적입니다. 회귀 오류(regression)가 발생하면, 누락된 사용 경로를 추가하고 손상된 버전과 수정된 버전에 대해 재실행할 수 있습니다. 기존 테스트들은 그 커버리지가 확보될 때까지 유지될 것입니다.
마지막으로, 원래의 허브(Hub) 모델 페이지를 해당 MIC와 연결하고자 합니다. 이를 통해 체크포인트(checkpoint)를 사용하는 개발자나 에이전트가 해당 체크포인트, 그 환경 및 예상 출력에서 테스트된 예시부터 시작할 수 있게 됩니다.
도움을 주고 싶으신가요? 커버리지 공간에서 미확보 모델을 선택하고, tmic 워크플로우를 시도하며, 사용 경로를 기여하거나 생성된 컨트랙트를 검토해 주세요.