키워드 채점기가 놓친 툴 호출 실패를 값싼 진단 사다리로 잡아낸다
Keyword Harnesses Fail Open: A Cheap Diagnostic Ladder for Tool-Use Claims in Small Language Models
무엇인가
키워드 매칭 기반 벤치마크는 모델이 실제로는 수행하지 않는 툴 사용을 했다고 채점할 수 있다. 이 논문은 스페인어/라탐 보안 도메인용 소형 모델 시리즈(VectraYX, 42M~1.1B, llama.cpp 기반 에어갭 배포 지향)에서 그런 거짓 양성을 문서화한다. VectraYX-600M(661.6M 파라미터, 단일 단계 프리트레이닝, 실현 믹스 기준 약 65%가 코드·기술 텍스트, 전용 SFT 없음, 스케줄 64%에서 영구 동결)과 VectraYX-1B(1,109M, 웹 중심 다단계 커리큘럼, 약 6B 토큰 규모의 전용 툴 SFT 단계 보유)는 디코더 구현, 32K 토크나이저, 특수 토큰 배치(ID 8 = <|tool_call|>, ID 9 = <|/tool_call|>)를 공유한다. 시리즈의 관대한 키워드 지표 B4에서 두 모델은 0.660 대 0.650으로 사실상 동일했지만, 실제 사용에서는 600M이 문맥에 맞는 bash_exec 호출을 스스로 내보내는 반면 1B는 JSON 구조를 한 번도 내보낸 적이 없었다.
어떻게 동작하나
저자가 제안하는 것은 엄격도가 단계적으로 올라가는 값싼 진단 사다리다. 첫 칸은 일반화 기준을 붙인 축자 재현(verbatim reproduction) 검사다. 모델 자신의 툴 SFT 학습 코퍼스에서 실제 예시를 가져오되 사용 가능한 MCP 도구를 선언하는 실제 시스템 프리앰블과 기대 포맷을 그대로 포함시키고, 프롬프트 절반을 학습 시점과 동일한 forward pass에 넣어 그리디 디코딩한 뒤, 잘 형성된 툴 호출 JSON이면서 인자가 학습 정답의 바이트 단위 복사가 아닌 그럴듯한 변형일 것을 요구한다. 결과는 범주적이었다. 600M은 6/6에서 성공했고, 1B는 테스트한 모든 체크포인트에서 0/4~6이었다. 관대한 하네스가 1B에게 준 점수는 툴을 호출한 것이 아니라 산문에서 툴을 언급한 것에 대한 것이었다.
무엇과 다른가
두 번째 칸인 첫 토큰 프로브는 실패 지점을 국소화한다. 툴 호출이 시작되어야 할 위치에서 1B가 <|tool_call|> 토큰에 부여한 확률은 10^-4~10^-5로, 600M이 그리디하게 내보내는 토큰에 사실상 확률 질량이 없는 상태다. 아카이브된 38개 체크포인트에 프로브를 재생하자 1B의 웹 중심 단계가 이전에 상속받았던 사전확률(prior)을 12,000 스텝 만에 거의 6자릿수만큼 지워버린 것으로 드러났다. 다만 36K 체크포인트에서 나온 잘 형성된 출력 3건은 학습 완성문의 바이트 단위 복제로 일반화가 0이었고, 이는 해당 프로브 예시가 1B의 1단계 학습 데이터에 오염되어 있음을 뜻한다. 즉 그 지점의 수치는 능력 상실이 아니라 기억된 사전확률이 씻겨나가는 과정으로 읽어야 한다.
어떻게 쓰나
진단에 근거한 수리 레시피는 다양성 있는 혼합 코퍼스(스페인어/영어 대화형 OASST + 툴 코퍼스 + 도메인 추론 트레이스), 임베딩 동결 해제, 5배 높은 학습률로 구성되며, 단일 대여 GPU에서 2,202 스텝, 약 3.3 GPU시간이 걸렸다. 실패한 전용 SFT 단계보다 약 3자릿수 적은 토큰이다. 결과적으로 축자 재현은 4/4가 되고 첫 토큰 확률은 0.996~0.998로 올라갔다. 선언된 5개 MCP 도구 중 선택이 필요한 8개 신규 프롬프트 가운데 7개에서 올바른 도구를 골라 학습에서 본 적 없는 인자(CVE 식별자, IP 주소, 검색 질의)를 추출했고, 대화형 질문인 8번째에서는 호출을 올바르게 억제했다. 전체 269개 코퍼스 행에서 유효 출력률은 0.100에서 0.959로 올랐고(600M은 0.926), 미학습 개체를 쓴 238개 프롬프트에서는 수리된 1B가 0.536으로 600M의 0.428을 앞섰다(짝지은 p = 0.004).
전제와 한계
임베딩 드리프트 검사는 수리가 어디에 착지했는지 보여준다. <|tool_call|> 임베딩 행의 코사인 유사도는 0.999996, 행 노름의 상대 변화는 1.5×10^-6으로 임의의 평범한 행과 구분되지 않았고, bf16 테이블의 97.7%는 학습 후에도 비트 단위로 동일했다. 이 디코더는 입출력 임베딩을 묶어 쓰므로 그 행은 네트워크가 조준해야 할 unembedding 방향이기도 하다. 따라서 이 검사는 토큰의 입력 벡터뿐 아니라 라우팅의 기하학적 목표까지 커버하며, 자연스러운 '죽은 임베딩' 가설을 배제한다. 토큰의 의미는 처음부터 잘 놓여 있었고, 수리는 주변 네트워크가 올바른 문맥에서 그 토큰으로 라우팅하도록 학습시킨 것이었다. 이 과정에서 계측기 자체의 결함도 하나 드러난다. 32,768×2048 bf16 테이블에 대해 torch.norm과 torch.linalg.vector_norm은 630.134705를 반환한 반면 명시적 sqrt(Σw²)는 fp32와 fp64 모두에서 635.1627을 반환했는데, 명시적 계산이 정확하고 라이브러리 리덕션이 이 크기에서 0.8% 오차를 낸 것이다.
저자가 명시한 한계는 적지 않다. 두 모델 모두 과발동한다. CVE나 셸 명령을 언급하는 no-call 프롬프트에서 호출 없이 답한 비율은 600M이 0.09, 수리된 1B가 0.17에 불과하다. 수리 레시피의 남은 두 재료(코퍼스 다양성, 학습률)를 분리하는 5회 팩토리얼에서는 모든 셀이 호출 포맷을 설치했지만, 가장 큰 대비인 '낮은 학습률에서 다양한 코퍼스의 억제 이점'은 부분 시드 반복에서 재현되지 않아 가설로만 보고된다. 일반화 배터리에는 스코어링 버그가 있었고(수정 후 600M 0.726→0.474, 수리된 1B 0.652→0.541), 72개 억제 프롬프트 중 18개가 중복이라 실효 n은 53이다. 원래 수리 체크포인트와 그 부모 모델은 인프라와 함께 소실되어 보고된 수치는 재현본에서 나온 것이고, 600M은 코사인 스케줄이 어닐링되지 않은 64% 동결 스냅샷이며, 두 모델의 비교는 ablation이 아닌 자연 실험이다. 수리된 1B가 평범한 대화형 질문에 유용하게 답한다는 증거도 없다.
개발자에게 남는 실무 지침은 두 문장으로 요약된다. 출력 포맷을 프리트레이닝 믹스에 넣어라. 그리고 툴 호출과 툴에 관한 문장을 구분할 수 있는 채점기로 툴 사용을 검증하라. 600M에 대한 전용 툴 SFT 실험은 호출 측 통과율은 올렸지만 게이트(호출하지 말아야 할 때 억제하는 능력)는 생기지 않았고, 더 큰 모델에서 증류한 데이터는 측정 가능한 효과가 없었다. 논문의 결론은 부트스트랩 코퍼스 구성이 소형 모델의 툴 호출 가능성 자체를 결정하는 게 아니라, 그 능력이 기본값으로 딸려오는지 아니면 나중에 공학적으로 만들어 넣어야 하는지를 결정한다는 것이다. 실패한 전용 단계보다 3자릿수 적은 토큰의 레시피가 성공했다는 사실은 SFT 토큰 볼륨이 어떤 개입이 통할지에 대해 아무것도 알려주지 않는다는 뜻이다.