이 글은 Kaggle Benchmarking Challenge 제출물입니다.
모든 것을 설명하려면 아마 별도의 연구 논문이 필요할 것 같지만, 좀 더 짧게 요약해봤습니다? 😅
이야기는 최첨단(frontier) 기술의 속도에 대한 대화에서 시작되었습니다. 저는 이러한 모델을 개발하는 사람들의 글을 읽었고, AI가 얼마나 발전했으며 다음에 무엇이 필요한지에 대해 이야기하고 있었습니다. 한편, 저는 케냐에서 우리가 사용하는 언어들에 대해 생각했습니다.
만약 이 시스템들이 이미 최첨단 수준에 도달했다면, Kalenjin은 어떨까요?
혹은 Kikuyu, Dholuo, Somali, 그리고 Maasai는요?
그 질문이 바로 **“누구를 위한 최첨단인가?”**가 되었습니다.
// Detect dark theme var iframe = document.getElementById('tweet-2098773920774074715-878'); if (document.body.className.includes('dark-theme')) { iframe.src =
개발 파일럿도 도움이 되었습니다. 제가 지나치게 엄격한 출력 파서(output parser)를 수정한 후, 여러 모델이 아홉 가지 예시 모두에서 정답을 맞혔습니다. 이 작은 호스팅 파일럿은 영어, 암하라어(Amharic), 요루바어(Yoruba)를 다뤘고, 저의 스와힐리어(Swahili) 관찰은 제 개인적인 경험에서 나온 것입니다. 저는 14개 언어 전체 계획을 실행한 것은 아니었습니다.
저는 자신이 정당화하고 싶은 결론부터 시작했습니다. 초기의 결과들이 그 결론에 도전장을 내밀었습니다. 기대했던 답을 벤치마크가 만들어내도록 하기보다는, 질문 자체를 발전시키도록 해야 했습니다.
그래서 저는 제가 알고 있는 문제로 돌아왔습니다: 케냐어(Kenyan languages) 번역입니다.
처음에는 칼렌진어(Kalenjin)가 너무 틈새 시장(niche)일까 봐 걱정했습니다. 하지만 저는 이 언어를 합니다. 그리고 작업해 왔습니다. 출력물을 보고 그것이 말이 되는지 개인적인 견해를 가질 수 있었습니다. 그 경험은 유용했습니다.
Four stages of the project: broad African-language tasks, Kenyan translation, harness experiments, and fresh native Kaggle runs.
실제로 작업할 수 있는 데이터를 선택하기
저는 제가 익숙했던 데이터셋인 African Next Voices Kenya를 선택했습니다. 다른 옵션들도 있었지만, 저는 이 데이터셋과 그 텍스트가 어떻게 수집되었는지 더 잘 알고 있었습니다.
KEMT—Kenyan Machine Translation Benchmark—는 범용 모델(general-purpose models)이 영어와 다섯 개 언어 사이에서 양방향으로 번역하는 것을 평가합니다:
영어 ↔ 칼렌진어(Kalenjin), 키쿠유어(Kikuyu), 돌루오어(Dholuo), 소말리어(Somali), 마사이어(Maasai).
초기 번역 코호트에는 다섯 개 언어에 걸쳐 548개의 영어 프롬프트가 포함되어 있었습니다. 여기에 개별적인 지역 변이형과 양방향을 포함하자, 이는 모델당 5,637개의 번역 항목이 되었습니다. 비용 계산 때문에 저는 이를 축소했습니다. 저는 그들의 고유한 지역 변이형을 유지하며 162개의 영어 프롬프트를 선택했고, 이것은 모델당 1,757개 항목이 되었습니다. 참고 자료는 데이터셋에서 가져왔으며, 다른 모델에게
이러한 변형들이 중요했습니다. 이 언어 레이블들은 다양한 음성 방언을 포괄할 수 있습니다. 예를 들어, Kalenjin의 Nandi와 Kipsigis 같은 dataset documents 그리고 여러 Kikuyu 방언들입니다. 저는 공급된 대체 문구를 그대로 유지했지만, 모든 변형을 방언별로 분류하거나 방언 특정 결과를 주장하지는 않았습니다.
?로 대체된 Kikuyu 문자: 파일 기록 확인하기
Kikuyu 추출물에는 제가 모델을 평가하기도 전에 문제가 있었습니다. 일부 ĩ와 ũ 문자가 물음표로 바뀌어 버린 것입니다. 여기 실제 예시가 있습니다. 영어 프롬프트 “How do you eat this?”에 대한 예시입니다:
Damaged export: ?r?aga at?a irio ici?
Older export: ũrĩaga atĩa irio ici?
Recovered text: ũrĩaga atĩa irio ici?
이 시점에서 AI의 제안은 데이터셋 제작자에게 연락하는 것이었습니다. 저는 Kikuyu 부분을 포기하기 전에 더 간단한 것을 시도하고 싶었습니다. 만약 이전 버전에는 여전히 문자가 남아있지는 않을까?
저는 Hugging Face 파일 기록을 되돌아보았습니다. older pinned export에는 깨진 문자가 있었지만, 여전히 복구할 수 있었습니다. 이 파일에서는 이전 텍스트를 Windows-1252로 인코딩하고 UTF-8로 디코딩하여 문자를 복원했습니다. 우리는 그 변환이 가역적이며, 손실된 문자가 ?로 대체되었을 때 복구된 문자열이 손상된 버전과 일치하는지 확인했습니다.
그렇게 174개의 선택된 변형을 복구했습니다. 저는 사용하기 전에 샘플들을 검사했고, 영어 선택 및 나머지 네 개 언어는 동일하게 유지되었습니다.
만약 비슷한 문제를 발견한다면, 해당 언어를 포기하기 전에 저장소의 파일 기록을 확인해 보세요. 문자 그대로의 ?는 이미 정보를 잃은 것이므로, 손상된 파일의 인코딩을 변경하는 것만으로는 복구되지 않습니다. 여기서 유용한 부분은 문자를 여전히 보존하고 있는 이전 사본을 찾는 것이었습니다. 만약 데이터셋 관리자들이 이 글을 읽고 있다면, 수정된 추출물이 다음 연구자에게 이러한 우회 과정을 줄여줄 것입니다.
이것은 벤치마크를 준비하는 것 자체가 데이터 작업임을 알려주는 초기 경고 중 하나였습니다. 리더보드는 여러분이 입력한 텍스트가 손상되었는지 여부를 알려주지 못합니다.
이 코호트는 의도적으로 작게 구성되고 선별되었습니다. 공용 학습-내보내기(training-export) 텍스트를 사용하므로, 모델들이 이것을 본 적이 없다고 주장할 수 없습니다. 이는 모든 언어에서 구사되는 모든 것을 대표하는 조사가 아니라 비교를 위한 출발점입니다.
테스트된 모델들
저는 광범위한 커버리지를 원했습니다: 다양한 연구소, 다양한 크기, 그리고 비싼 모델과 저렴한 모델 모두요. 이상적으로는 Kaggle 카탈로그에 있는 7개 연구소 각각에서 최고 수준의 모델을 최소 하나씩 원했습니다.
접근성과 성공적인 완료는 서로 다른 것이었습니다.
10월 9일 스냅샷에는 1,757개 항목 전체를 다루는 15개의 완전한 네이티브 평가가 있습니다:
| 제공업체 | 완료된 모델 |
|---|
| Google | Gemini 3.1 Pro Preview; Gemini 3.7 Flash; Gemini 3.8 Flash; Gemini 3.6 Flash; Gemini 3.5 Flash-Lite |
| ... | |
Qwen 3 Next 80B Instruct는 네 가지 언어를 완료했지만, 384개 번역 중 280개를 저장한 후 Kalenjin 실행에서 시간 초과가 발생했습니다. 저는 이것을 완전 모델 순위에서 제외했습니다. 이전에 Qwen 3 235B 시도는 과부하 오류를 겪었고, Grok은 모델 접근 오류를 반환했습니다. 이것들은 품질이 제로인 번역이 아니라 누락된 평가입니다.
그 모든 것 이전에, 구독형 도구들이 있었습니다
첫 번째 실질적인 장애물은 예산이었습니다. 저의 초기 Kaggle 할당량은 하루 10달러, 한 달에 100달러였습니다. 더 큰 코호트의 비용을 예측한 후, 저는 작업을 수행할 더 저렴한 방법을 찾기 시작했습니다.
자, 케냐에서 제한된 예산으로 일하는 동료라면 가지고 있는 것으로 무언가를 시도해야죠 😅.
저는 평소 개발에 Codex를 사용합니다. 제 20달러 구독은 이미 그 도구를 통해 Astra와 같은 모델에 접근할 수 있게 해주었고, 모든 API 토큰에 대해 개별적으로 비용을 지불하는 대신 구독 할당량을 사용했습니다. 이것이 사용 한도 내에서 탐색할 실용적인 경로가 되었습니다.
Anthropic 모델에 접근하기 위해 Claude Code에 돈을 좀 써야 했고, 일부 오픈 모델에는 CommandCode를 사용했습니다. OpenCode 경로도 시도해 보았습니다. Google 모델의 경우, 이미 학생 Pro 계정이 있어서 Antigravity가 도움이 되었습니다. Cursor를 통해 Grok 모델을 사용해 보고 싶었지만, 제 학생 구독이 만료되었고 예산으로는 다른 구독까지 늘릴 수 없었습니다.
저는 이러한 하네스(harnesses)들을 통해 번역을 실행하고 응답을 저장한 다음 로컬에서 점수를 매겼습니다. 구독, API 추정치, 배치 처리, 재시도 등을 거치면서 ARC-AGI와 같은 벤치마크와 관련된 대규모 평가를 수행하는 것이 얼마나 비용이 많이 들 수 있는지 깨닫기 시작했습니다. 심지어 저의 훨씬 작은 실험조차 타협을 필요로 했습니다.
그 실험들은 유용했습니다. 또한 모델 이름만으로는 평가 전체를 설명할 수 없다는 것도 가르쳐 주었습니다. 하네스, 그 지침(instructions), 사용 가능한 제어 장치(controls), 그리고 출력을 반환하는 방식이 결과를 바꿀 수 있기 때문입니다.
저는 이 실행 결과들을 네이티브 Kaggle 리더보드에 올리고 싶어서 Kaggle 벤치마크 팀에 이메일을 보냈습니다. 그들의 답변은 네이티브 결과는 반드시 Kaggle의 관리형 추론 파이프라인을 통해 나와야 한다는 점을 명확히 했습니다. 외부 하네스 결과는 단순히 가져올 수 없었습니다. 저는 그 탐색을 중단하고, 네이티브 벤치마크를 완료할 수 있도록 Kaggle 모델에 집중했습니다.
할당량 이상의 의미가 담긴 답변
저는 Head of Kaggle Competitions Program Management 직책의 서명이 있는 Addison Howard로부터 답장을 받을 것이라고 예상하지 못했습니다. 그런 위치에 있는 사람이 벤치마크를 진지하게 받아들이는 것을 보니, 저는 그것을 끝내야겠다는 동기 부여가 더욱 커졌습니다.
Addison Howard's reply confirming the quota increase and explaining that the team was investigating temporary Grok and Qwen issues.
이것은 저에게 추가 크레딧 이상의 의미였습니다. 계속 나아갈 수 있는 격려였기 때문입니다.
제 수당은 하루 $50, 월 $500로 인상되었습니다. Addison은 또한 팀이 백엔드에서 임시 Grok 및 Qwen 문제를 디버깅하고 있다고 설명했습니다. 이는 접근 실패의 맥락을 파악하는 데 도움이 되었습니다.
원래 저는 각 연구소에서 하나의 프론티어 모델(frontier model)을 목표로 했습니다. 추가 할당량 덕분에 사용 가능한 더 많은 모델들을 탐색할 수 있었고, 완성된 네이티브 명단(native roster)을 15개까지 늘릴 수 있었습니다. 대략적인 추정으로, Kaggle 측 실험은 전체적으로 **약 $100 상당의 추론 크레딧(inference credit)**을 사용했으며, 구독료는 별도였습니다.
저는 여전히 로컬 하네스 실행(local harness runs)을 계속하고 나중에 Kaggle 결과와 비교할 계획이며, 각 경로를 명확하게 표시할 것입니다. 이번 제출물에 대한 결과는 신선한 네이티브 Kaggle 실행에서 나온 것입니다.
배치 처리(Batching)가 영리했지만… 더 많은 작업이 되기까지
처음에는 프롬프트 오버헤드(prompt overhead)를 절약하기 위해 여러 번역을 하나의 요청에 담았습니다. 이는 합리적인 생각이었고, 일부 모델들은 이를 잘 처리했습니다.
하지만 다른 모델들은 그렇지 않았습니다. 형식 문제, 출력 ID 문제, 제공업체 구성 오류, 속도 제한(rate limits), 그리고 특히 기억에 남는 GLM 응답이 있었습니다:
죄송합니다만, 이 특정 텍스트들에 대한 번역은 번역 평가 또는 테스트 세트의 일부인 것 같습니다.
실제로 저는 번역 평가를 실행하려고 했습니다. 모델은 상황을 정확하게 파악하고 초대를 거절한 것입니다 😅.
저는 모든 모델에 걸쳐 일관되게 작동하는 규칙이 필요했습니다. 명시적인 거부는 빈번역으로 받아들여져 그에 따라 점수가 매겨질 것이었습니다. 제공업체 또는 전송 실패는 잘못된 답변으로 조용히 계산되기보다는 실행을 불완전하게 만들 것입니다.
결국, 저는 네이티브 작업을 요청당 문장 하나로 변경했고, 모델에게 번역만 반환하도록 요청했습니다. 저는 JSON 엔벨로프(envelope)나 모델 생성 ID를 요구하지 않고 반환된 텍스트에 점수를 매겼습니다.
그것은 전체 포맷팅 실패 카테고리를 제거했습니다. 또한 새로운 완전 모델 평가마다 1,757개의 요청이 필요했습니다. 기다리는 시간이 프로젝트의 실제 부분이 되었습니다. 한때 제 일지에는 기본적으로 다음과 같이 적혀 있었습니다: 실행을 시작하고, 그리고 기다리기.
단일 요청만으로는 제공업체의 제한을 없애지 못했습니다. 여러 언어 작업을 동시에 실행하는 것은 여전히 과부하 문제를 일으켰습니다. 그래서 저는 다시 한번 한 번에 하나의 언어를 실행하는 방식으로 돌아갔습니다.