Skip to content
Guides5 min read

캘리브레이션 회의 계측하기

주석 팀은 이미 노밍 세션을 하고 있고, 어노테이터가 어떻게 생각하는지 알고 싶어 합니다. 멀티플레이어 룸은 실시간 일치도 미터로 캘리브레이션 회의를 측정하고, Think-Aloud 모드는 소리 내어 말한 추론을 로컬에서 LLM 없이 기록합니다.

Potato Team

주석 팀이라면 어디나 서툴게 하고 있는 일이 둘 있습니다. 도구가 도와주지 않기 때문입니다. 하나는 화면 공유로 진행되고 아무 흔적도 남기지 않는 캘리브레이션 회의, 다른 하나는 어노테이터가 그 라벨을 골랐는지 이해하는 일인데 보통 아무도 채우지 않는 자유 입력 상자로 끝납니다. Potato 2.7은 둘 다 계측합니다. 실시간 일치도 미터가 붙은 라이브 노밍 룸, 그리고 음성 인식을 로컬에서 돌리는 사고구술 기록기입니다. 어느 쪽도 LLM이 필요 없습니다.

아무 증거도 남기지 않는 회의

세 명 이상이 붙는 주석 프로젝트를 해 봤다면 노밍 세션을 해 본 것입니다. 전원이 같은 항목 몇 개에 라벨을 붙이고, 통화에 모여, 갈린 지점을 두고 다투다가, 결국 지침이 실제로 무슨 뜻인지에 수렴합니다.

효과는 있습니다. 그리고 완전히 계측되지 않은 채로 남습니다. 토론 전에 사람들이 갖고 있던 표는 사라집니다. 누가 생각을 바꿨는지, 설득돼서 바꿨는지 아니면 선임 동료가 먼저 말해서 바꿨는지도 사라집니다. 그리고 그 회의가 일치도를 조금이라도 올렸는지는 아무도 답할 수 없는 질문인데, 아무도 재지 않았기 때문입니다.

멀티플레이어 룸은 그 세션을 도구 안으로 옮깁니다.

실시간 노밍 룸: 공개된 블라인드 투표, 실시간 일치도 미터, 기록된 동조 전환세션이 진행 중인 노밍 룸

yaml
rooms:
  enabled: true
  who_can_create: any
  persist_votes: true
  schema: sarcasm

/rooms를 열어 하나 만들면 통화에서 소리 내어 읽어 줄 수 있는 여섯 글자 코드가 붙습니다. 흐름은 의도적으로 짜여 있습니다.

  1. 전원이 블라인드로 투표합니다. 구성원은 누가 투표했는지는 볼 수 있지만 무엇에 투표했는지는 결코 볼 수 없습니다. 서버에서 강제하므로 첫인상이 실제로 독립적입니다.
  2. 호스트가 공개합니다. 이 시점에 블라인드 투표는 바뀌지 않게 굳습니다.
  3. 그룹이 토론합니다. 사이드 채팅에서든 통화에서든 상관없습니다.
  4. 누구든 투표를 바꿀 수 있습니다. 공개 이후의 모든 변경은 무엇에서 무엇으로 바꿨는지, 그 시점의 다수 의견이 무엇이었는지와 함께 기록됩니다.

흥미로운 것은 네 번째 단계입니다. 공개 이후의 투표 변경은 투표와 같은 사건이 아니라 알려진 다수 의견 앞에서 일어난 변경입니다. 이를 기록해 두면 구성원별 동조 기록이 남고, 그래서 어떤 어노테이터가 매번 빠짐없이 다수 쪽으로 넘어간다는 것을 알아챌 수 있습니다. 그 사람의 일치를 독립적인 증거로 취급하기 전에 알아 둘 값어치가 있습니다.

일치도 미터가 “할 만한 일이었나?”에 답합니다

Krippendorff α는 공개된 항목에 대해 실시간으로 두 번 계산됩니다. 한 번은 블라인드 투표 기준, 한 번은 현재 투표 기준입니다. 그 차이가 세션의 노밍 효과이며, 세션이 진행되는 동안 화면에 표시됩니다.

이 숫자가 회의에 책임을 지웁니다. 한 시간의 토론이 α를 0.61에서 0.78로 옮겼다면 그 시간이 뭔가를 사 왔다는 것을 압니다. 0.61에서 0.62로 옮겼다면, 그 불일치가 해석의 문제가 아니라는 것을 배운 셈입니다. 지침의 문제이고, 아무리 이야기해도 고쳐지지 않습니다. 가서 지침을 다시 쓰십시오.

알아 둘 변형이 둘 있습니다. Huddle은 팀이 지금 실제로 의견이 갈리는 항목들로 룸을 채우며, 이는 주석 상태에서 실시간으로 계산되므로 판정의 동기식 버전이 됩니다. Shadow 룸은 교육 중인 사람이 선임 어노테이터가 작업하는 모습을, 어느 텍스트 구간을 강조하고 있는지까지 실시간으로 지켜보게 해 줍니다. 옆에 앉아 주석하는 모습을 보는 것에 가장 가까운 형태입니다.

룸은 JSONL 로그로 이벤트 소싱되므로 진행 중인 룸이 서버 재시작을 견디고, 그 로그가 세션의 감사 기록 역할도 겸합니다. WebSocket은 쓰지 않고 클라이언트가 커서를 붙여 폴링하므로, 룸은 어떤 WSGI 배포에서도 동작합니다.

한 번도 담아내지 못한 추론

또 하나의 조용한 실패는 근거입니다. 대부분의 도구가 자유 입력 상자를 제공하고, 대부분의 어노테이터는 거기에 “뻔함”이라고 적거나 아무것도 적지 않습니다.

게으름이 아닙니다. 자기 추론을 글로 옮기는 일은 그냥 추론하는 것보다 실제로 느리고, 작업이 400개짜리라면 근거 상자가 가장 먼저 버려집니다.

Think-Aloud 모드는 방식을 바꿔 그 마찰을 없앱니다. 어노테이터는 작업하면서 그냥 말하면 됩니다.

감지된 음성 라벨과 함께 말한 그대로 남은 추론 전사본라벨이 감지된 Think-Aloud

yaml
thinkaloud:
  enabled: true
  schema: politeness
  model: tiny.en

음성 인식은 faster-whisper로 로컬에서 돌아가며, 39 MB짜리 tiny.en 모델에서 CPU로 실시간이 나옵니다. 오디오는 기기를 떠나지 않고, 호출할 클라우드 API도 토큰당 청구서도 없습니다. 민감한 데이터가 많은 곳에서는 이것이 “쓸 수 있다”와 “법무팀이 안 된다고 했다”를 가릅니다.

사고구술 프로토콜은 이 모든 것이 계산적으로 다뤄지기 한참 전부터 사람이 어떻게 결정을 내리는지 연구하는 표준이었습니다. 다만 주석 도구 안으로는 들어오지 못했는데, 누군가에게 녹음기에 대고 말하게 한 다음 그것을 손으로 전사하는 일은 아무도 지속하지 못하는 작업 흐름이기 때문입니다.

말한 그대로, 의도적으로

전사본은 말한 그대로 저장되며 일부러 요약하지 않습니다. 게으름이 아니라 실제 설계 결정입니다. 사고구술 프로토콜을 바꿔 말하면 그 자료 자체가 오염됩니다. 머뭇거림, 자기 정정, “음, 비꼬는 걸 수도 있는데, 그런데…” 같은 것이 곧 데이터입니다. 그것을 깔끔하게 정리한 요약은 다르고 훨씬 덜 쓸모 있는 물건입니다.

어노테이터는 규칙 기반 파서가 감지하는 정해진 표현을 써서 음성으로 라벨을 확정할 수도 있습니다.

  • "I label this Polite"
  • "My answer is impolite"
  • "Final answer: neutral"

그 표현만 확정합니다. 생각하는 동안 한 말은 모두 무시되며, 그래서 규칙 기반 파서로 충분합니다. 파이프라인 어디에도 LLM이 없고, 무슨 뜻이었는지 판단하는 모델도 없습니다. 나중에 새 표현을 말하면 마지막 확정이 이깁니다.

머뭇거림 신호(무음 청크 수, 군말 단어 수)도 모델이 아니라 산술로 계산되어 결정론적으로 나옵니다. 어떤 항목에서의 긴 멈춤은 난이도의 꽤 괜찮은 대리 지표이고, 모으는 데 비용이 들지 않습니다.

근거를 넘어서, 이것이 중요한 이유

여기서부터가 Potato 2.7의 나머지와 이어지는 대목입니다.

Think-Aloud는 사람의 사고 사슬 기록기입니다. 사람이 실제로 어떻게 추론해서 라벨에 이르는지를 담아냅니다. 나중에 다듬어 쓴 정당화가 아니라, 헛디딤까지 포함해 일어나는 그대로의 추론입니다.

Potato의 프로세스 보상 주석은 모델에 대해 같은 일을 합니다. 모델의 사고 사슬을 단계로 나누고 단계별로 채점합니다.

같은 항목, 두 개의 사고 사슬, 하나는 사람 것이고 하나는 모델 것입니다. 나란히 놓고 추론이 어디서 갈리는지 볼 수 있습니다. 이것은 정말로 새로 생긴 자산이고, 더 나은 프로세스 보상 데이터의 원재료이기도 합니다. “모델이 틀린 이유로 맞는 답을 냈다”는 것이야말로 최종 답만 채점해서는 볼 수 없는 실패이기 때문입니다.

Potato는 두 수집 창구를 모두 제공합니다. 둘 사이의 차이를 대신 계산해 주지는 않습니다. 그것은 기능이라기보다 연구 문제이고, 우리가 지어낸 지표보다는 자료 자체를 건네는 편이 낫다고 봅니다.

더 읽을거리