요즘 개인적으로 Obsidian 플러그인을 하나 만들고 있다(아직 공개 전이다). 원문 자료를 넣으면 LLM이 읽고 개념별 노트로 정리해주는 도구인데, 자료를 여러 번 넣다 보면 같은 제목의 노트가 두 번 만들어지는 일이 생긴다. 그러면 플러그인이 두 노트를 OpenAI API에 보내서 한 번 더 판단시킨다. 같은 개념이 우연히 두 번 만들어진 거면 합치고, 제목만 같고 내용이 다르면 구분되는 이름으로 바꾼다. “합칠까 말까” 정도의 판단 하나하나에 매번 LLM 호출 전체를 쓰는 게 아깝다는 생각을 하던 차에, 딱 이런 “저차원 판단”만 전담하는 모델이 있다는 얘기를 들었다. TypeSafe의 Jev, 그리고 그 오픈소스 대항마 Laya. 실제로 지금 하고 있는 판단에 붙일 수 있는지 확인해봤다.
System One 모델이라는 것 (ModernBERT, 421M)
Jev와 Laya는 LLM이 아니다. 텍스트를 생성하지 않고, 상황(state)과 타입이 정해진 질문들을 주면 확률과 함께 답만 돌려준다. choice(선택지 중 하나), score(순서형 점수), noul(참일 확률) 세 가지 primitive로만 답한다. 파싱할 것도, 환각을 부릴 자연어도 없다는 게 요지다. Jev는 프로프라이어터리로 2026-09-15에 얼리 액세스로 나왔고, Laya는 이걸 오픈소스로 재현한 프로젝트다 — ModernBERT-large 기반 421M 파라미터, Apache 2.0.
원본을 잘못 짚었다 — GGUF와 GitHub 미러
Laya를 실제로 써보려고 찾다가 두 번 헛다리를 짚었다. 처음엔 허깅페이스에 있는
“GGUF” 파일을 보고 Ollama나 LM Studio에 바로 올릴 수 있을 줄 알았는데, 그 파일은
llama.cpp가 쓰는 표준 GGUF가 아니라 ggmlc라는 별도 컴파일러가 만든 형식이었다.
실제 Ollama 앱에 넣어도 안 열린다.
두 번째는 원본 저장소 자체를 잘못 짚은 거였다. 처음 찾은 GitHub 저장소
(he-jev/laya)는 겉보기엔 원본이 맞아 보였다 — README 내용이 실제 모델 정보와
정확히 일치했다. 그런데 그 README 맨 아래 “Links” 섹션
자체가 자기 자신이 아니라 다른 주소를 GitHub 원본으로 가리키고 있었다. 확인해보니
진짜 원본은 스타 27,891개짜리 NandhaKishorM/laya였고, 처음 본 저장소는 스타
7개짜리 미러였다. 내용이 진짜라고 해서 원본이라는 뜻은 아니었다.
속도 — 광고한 33ms는 GPU 얘기였다
테스트는 GPU 없는 집 PC(12코어, 가용 RAM 23GB)에서 했다. pip install laya로
설치하고 영어 체크포인트(convaiinnovations/laya)를 받아서 돌려봤다. 콜드 로딩 23초(모델 다운로드 포함), 로드 후 메모리 2.7GB.
호출당 지연시간은 평균 1.3초가 나왔다.
README가 내세우던 “33ms, 39.5ms” 같은 수치와 30배 넘게 차이가 나서 다시 확인해보니, 그 벤치마크는 Tesla T4 GPU에서 잰 거였다. 이번 테스트는 GPU 없는 CPU였고, 421M 파라미터 트랜스포머를 CPU로 돌리면 이 정도 격차는 흔한 일이다. “마이크로초 단위 게이팅”이라는 마케팅 문구는 GPU를 갖춘 환경 얘기였고, CPU만 있는 환경에선 초 단위로 다시 계산해야 했다.
정확도 — 과거 실측 데이터로 재본 결과 (23건 중 78%)
마침 플러그인을 실제로 돌려보며 테스트하던 노트 보관소에, 예전에 생긴 중복 노트들이 그대로 남아 있었다. 같은 원문 기사가 서로 다른 자료 파일 두 개에 겹쳐 들어가서 생긴 진짜 중복들이다. 이 17쌍을 원래 노트와 중복 노트 양쪽 다 직접 열어서 정말 같은 개념인지 확인한 뒤(전부 “같음”이 정답이었다), Laya에게 “이 두 노트가 같은 제목을 공유하는데, 같은 개념이냐 다른 개념이냐”고 물었다. 여기에 더해, 실제로는 이런 사례가 남아있지 않았던 “제목만 같고 완전히 다른 개념” 상황도 서로 무관한 노트 쌍 6개를 골라 직접 만들어 넣었다.
결과는 전체 23건 중 18건(78%) 정답 — 진짜 중복 17건 중 14건, 합성 오답 케이스 6건 중 4건을 맞혔다.
진짜 문제는 정확도가 아니라 확신이었다 — confidence와 temperature
숫자만 보면 “아직 부족하지만 써볼 만하다” 싶었는데, 답 하나하나를 뜯어보니 더 심각한 문제가 있었다. 맞힌 답들 중에도 confidence가 0.01, 0.011, 0.016처럼 사실상 동전 던지기 수준인 경우가 수두룩했다. 그리고 결정적으로, 완전히 다른 내용의 두 노트를 “같다”고 틀리면서 confidence 0.802, 0.896처럼 높은 확신을 보인 경우가 있었다.
모델을 로드하는 시점에 이미 경고가 떠 있었다: 이 체크포인트는 손상된 temperature 값을 갖고 있어서 confidence를 믿을 수 없다고, 모델 스스로 알려주고 있었다. Jev/Laya 같은 System One 모델의 핵심 가치는 “확률을 믿고 임계값으로 자동 게이팅할 수 있다”는 건데, 지금 이 체크포인트로는 그 전제 자체가 무너져 있었다.
파인튜닝하면 되지 않을까 — 그런데 병목은 GPU가 아니었다 (RLCD, Kaggle 2×T4)
공식 문서(docs/finetune.md)를 보면 절차는 이렇다: Kaggle 무료 2×T4 GPU에서
RLCD로 학습하고, 학습 데이터에서 최대 400개를 따로 떼어 confidence
temperature를 다시 fit한다. GPU는 무료로 구할 수 있으니 문제가 아니었다.
진짜 병목은 데이터였다. 학습에 필요한 건 정답 라벨이 아니라 “state + 질문들 + teacher 모델이 각 선택지에 준 확률 분포”이고, 문서의 데모조차 1,200건(질문 6,000개), 실제 벤치마크는 3만 건 규모였다. 지금 손에 있는 실측 케이스는 23개뿐이다 — 유의미한 파인튜닝을 하려면 플러그인이 중복 판단을 할 때마다 그 결과를 확률과 함께 꾸준히 모아야 하는, 하루이틀에 끝날 일이 아니었다.
Jev는 다를까 — 애초에 파인튜닝이 안 된다 (LoRA 불가)
Laya의 파인튜닝 부담을 보고 “그럼 Jev를 쓰면 되지 않나” 싶어서 찾아봤는데,
TypeSafe 쪽 답은 정반대였다. Jev는 고객 데이터로 파인튜닝이나 LoRA 적용이
아예 안 된다. 모든 계정이 같은 가중치를 공유하고, 커스터마이징은 오직
state에 도메인 데이터를 채우고 instructions/criteria에 판단 기준을
구체적으로 적어주는 프롬프트 레벨에서만 가능하다.
정리하면 방향이 정반대다. Laya는 “직접 개선할 수 있다”는 게 장점이지만 그 개선을 하려면 방금 본 데이터·GPU·캘리브레이션 작업을 다 거쳐야 쓸만해지고, Jev는 그 작업 자체가 없는 대신 정확도 상한이 벤더가 만들어 둔 모델 성능에 고정된다.
결론
Laya는 지금 단계에서 더 쓰지 않기로 했다. 중복 노트 판단은 지금처럼 OpenAI API 호출로 계속 처리한다 — 정확도도, 확신에 대한 신뢰도도 이미 검증된 방식을 굳이 불확실한 경로로 바꿀 이유가 없었다. Jev는 아직 계정에 접근 권한이 열리지 않아서 이번엔 시도조차 못 해봤고, 나중에 열리면 그때 다시 볼 생각이다.
남는 생각
이번 조사에서 제일 크게 배운 건 정확도 숫자 자체가 아니라, “확신”이라는 값을 마케팅 문구만 보고 믿으면 안 된다는 거였다. 78%라는 숫자만 봤으면 “쓸 만할지도”라고 넘어갔을 텐데, 답 하나하나를 열어보니 틀린 답에 오히려 더 높은 확신이 붙어 있었다. 속도 벤치마크도 마찬가지였다 — GPU에서 잰 33ms를 CPU 환경 기대치로 착각할 뻔했다. 숫자는 항상 어떤 조건에서 나온 건지까지 같이 봐야 한다는 걸 다시 확인한 하루였다.