I turned Jev into a (lousy) chatbot
Jev를 형편없는 챗봇으로 만들어 봤습니다
jevchat은 Jev에게 매 단계마다 다음에 올 문자나 토큰을 묻고, 확률 분포에서 하나를 뽑아 답변을 이어가는 채팅 도구입니다. 알파벳과 탐색 전략을 바꿔가며 문자 단위 샘플링, 이진 탐색, 빔 서치 등을 실험할 수 있지만 API 비용은 상당히 비현실적입니다.
- 주제
AI 요약
jevchat은 Jev를 일반적인 챗봇처럼 감싸는 대신, 답변을 한 번에 생성하지 않고 한 기호씩 만들어 갑니다. 매 단계마다 사용자 질문과 지금까지 작성한 답변을 Jev에게 전달하고, 다음에 올 기호를 고르도록 합니다. 후보에는 문자나 토큰 목록과 STOP 항목이 들어갑니다. Jev가 각 후보의 확률을 반환하면 sampler가 정규화된 분포에서 하나를 뽑고, 답변에 붙인 뒤 같은 과정을 반복합니다. STOP이 선택되면 생성을 끝냅니다.
■ 설치와 실행
프로젝트는 Python 패키지 관리 도구 Poetry를 사용합니다. poetry install로 설치한 뒤 pyproject.toml 옆의 .env에 api_key=...를 넣습니다. JEV_API_KEY와 TYPESAFE_API_KEY 환경 변수도 인식하지만, .env 값이보낸 환경 변수보다 우선합니다. 대화형 모드는 poetry run jevchat, 한 번만 질문하는 모드는 poetry run jevchat ask 'do people need water?', 지원하는 알파벳 목록은 poetry run jevchat alphabets, 각 모드 비교는 poetry run jevchat bench로 실행합니다.
생성 중에는 답변이 실시간으로 표시됩니다. 화면에는 symbols/s, characters/s, API 호출당 밀리초, 전체 경과 시간, 직전 단계에서 Jev가 높게 평가한 후보 몇 개가 함께 나옵니다. Ctrl-C를 한 번 누르면 진행 중인 요청이 끝난 뒤 생성을 멈추고 부분 답변을 보존합니다. 두 번째로 누르면 즉시 중단합니다. 대화 모드에서는 부분 답변도 대화 기록에 남고, ask 명령은 취소 시 종료 코드 130을 반환합니다. /help, /alphabet, /temp, /stop-bias, /reset, /stats, /exit 같은 대화 명령도 제공합니다.
■ 알파벳과 샘플링 전략
두 축을 조합해 실행합니다. -a/--alphabet은 Jev가 고를 후보 집합을 정하고, -s/--strategy는 그 분포를 얻는 방식을 정합니다. choice는 전체 알파벳을 한 번에 제시하는 기본 전략입니다. 후보 순서를 섞어 Jev의 위치 편향을 줄이며, --no-shuffle-criteria를 쓰면 이 처리를 끕니다. --ensemble 4처럼 여러 순서를 병렬로 물어 평균을 내는 방식도 제공합니다.
bisect는 정렬한 알파벳을 두 그룹으로 나눠 앞쪽인지 뒤쪽인지 묻습니다. 그룹이 충분히 작아지면 내부에서 최종 후보 하나를 고릅니다. 기본 설정은 그룹 크기 20까지 양쪽 질문을 모두 사용하며, --bisect-cutoff 32 --no-bisect-swap으로 비용을 줄일 수 있습니다.
buckets는 후보를 여러 질문으로 나누고 각 질문에 OTHER 탈출 항목을 추가합니다. 255개를 넘는 후보도 처리할 수 있는 유일한 전략입니다. 그래서 words1k, bpe2k, bpe5k 같은 큰 알파벳은 -s buckets와 함께 사용합니다. refine은 먼저 bucket으로 후보를 줄인 뒤 승자에게 다시 질문하고, 마지막으로 nucleus를 재평가합니다. 프로젝트 설명에 따르면 올바른 기호에 배정되는 확률을 두 배로 만들고, 약 19배 넓은 어휘를 분해해 처리합니다.
알파벳에는 lower26처럼 a-z와 공백만 담긴 목록, ASCII 전체, 토큰 목록, 단어 약 1,000개, BPE 2,000개와 5,000개 목록이 있습니다. -t 0을 쓰면 확률적으로 뽑지 않고 가장 높은 후보를 선택합니다. 빔 서치 -b 3은 답변 후보 세 개를 동시에 유지합니다. 살아 있는 빔 하나와 한 단계에 한 번씩 점수를 사용하며, 빔 폭이 1보다 크면 temperature, top_p, top_k는 적용하지 않고 확률 순위로 빔을 정렬합니다.
■ symbol과 hypothesis 표현
Jev에게 후보를 제시하는 방식도 바꿀 수 있습니다. symbol 표현에서는 a, i, the처럼 기호 자체를 보여주고, Jev가 머릿속으로 현재 답변 뒤에 붙인 결과를 판단하게 합니다. 반면 hypothesis 표현에서는 기호를 이미 붙인 완성 문장을 후보로 제시합니다. 예를 들어 현재 답변이 The capital of France is Par라면 ...Para, ...Pari, ...Pars 같은 결과 문장과, 답변을 그대로 둔 STOP 문장을 평가하게 합니다.
작성자는 hypothesis 방식이 프로젝트에서 가장 큰 개선이라고 설명합니다. Jev가 원래 결정 모델에 가까운 방식으로 완성된 문자열을 비교하게 되기 때문입니다. 문자 알파벳에서 top-1 결과는 대략 세 배가 되었고, 올바른 기호에 모이는 확률 질량은 두 배가 되었습니다. 기호별 설명을 붙여 질문하는 방식보다 입력 토큰도 적게 듭니다.
이 프로젝트는 재미를 위한 실험이며 비용은 다소 비현실적이라고 밝힙니다. Claude의 도움으로 샘플링 알고리즘과 전략을 구현했습니다. pytest를 실행하면 네트워크와 API 키 없이 158개 테스트를 수행합니다. 생성 루프에는 스크립트형 가짜 클라이언트를 쓰고, HTTP 계층은 httpx.MockTransport로 대체합니다. 다만 jevchat bench는 실제 API를 호출합니다.
■ Hacker News 반응
- @ericpruitt — 디지털판 Morty와 죽음의 수정의 대화입니다. 수정은 자신이 어떻게 죽을지 보여주고, Morty는 자신이 원하는 삶과 함께 죽는 모습을 보는지에 따라 말을 반복해서 결정합니다. https://youtu.be/YjepJlvkdKs?t=51
- @lwansbrough — 현재 단어 완성 상태를 조회해서 짧은 단어 후보 목록을 반환해 보세요. 호출 횟수를 줄일 것 같습니다.
- @OtherShrezzing —
write me a short story라고 하자a story라고 답했습니다. 모델의 농담에 웃었다는 사실을 처음으로 알아차린 순간인 것 같습니다. - @phoghed — 예전 text-davinci 모델이 아무 말이나 통째로 지어내던 시절에는 정말 웃긴 완성이 나오곤 했습니다. 초기 ChatGPT 모델이 제가 상상한 인도 커버 밴드 The Needful Dead의 꽤 웃긴 트랙 목록을 만들어 준 적도 있습니다. 지금은 대화 기록에 없어서, Sam이 인종차별적으로 해석될 만한 모델 출력을 전부 소급해서 지운 것 같습니다.
- @Bluestein — 하나의 블랙박스로 다른 블랙박스를 디버깅하는군요. 재미있습니다.
- @applfanboysbgon — 무의미한 아이디어에서 나쁜 결과가 나올 때까지 걸리는 시간이 줄었습니다. 좋은 소프트웨어는 보이지 않고, 이제는 취미 프로젝트 아이디어까지 무의미하게 수확되는 것 같습니다. 그 아이디어의 유일한 목적은 직접 만들고 배우는 즐거움이었는데 말입니다.
- @cyanydeez — 이제 LLM은 주요 고속도로와 같습니다. 모두가 차선을 하나 더 늘리면 소프트웨어 정체가 해결될 것처럼 생각하지만, 수요만 늘어날 뿐 효율은 높아지지 않습니다. 정체 원인은 사람들이 사용량을 평가하고 빈 공간을 채우는 방식에 있습니다. 수십 년 동안 컴퓨터를 업그레이드했지만 소프트웨어가 사양을 채우도록 비대해진 것과 비슷합니다.
- @margalabargala — 좋은 아이디어는 수많은 나쁜 아이디어에서 살아남은 결과입니다. Slack은 과장된 IRC에 불과하지만 수십억 달러의 가치를 얻었습니다. Dropbox도 rsync로 사소하게 구현할 수 있지만 수십억 달러 규모가 됐습니다.
- @petesergeant — 솔직히 제 글을 손으로 직접 작성하는 과정은 꽤 즐거웠습니다.
- @jorl17 — 저도 비슷한 일이 있었습니다. 누군가 이미 해봤을 것이라고 생각해서 집에 돌아가면 찾아보려고 했습니다. 그런데 이렇게 빨리 Hacker News에 올라올 줄은 몰랐습니다.
- @digilypse — 저도 시도했지만, 이 내용은 이미 공식 문서에서 다루고 있습니다. 그래서 대단한 발견이라고 보기는 어렵습니다. https://docs.typesafe.ai/model-jaggedness/jev-1.13#generatio
- @radarsat1 — 단일 토큰 예측과 토큰 logit 출력을 사용하는 방식은 Jev와 비교해 전반적으로 어떤가요? 지금까지 읽은 내용으로는 Jev가 여전히 이런 방식보다 앞서는 것 같습니다. 하지만 아키텍처만 보면 왜 그런지 분명하지 않습니다. 사실 Jev도 내부적으로 똑같은 일을 할 가능성이 있으니, 결국 차이는 무엇인지 궁금합니다.
- @petesergeant — Jev에는 Qwen으로 가능한 가장 단순한 구현보다 분명히 나은 비밀 소스가 있습니다. OpenAI가 Luna-5.6에 연결하고 최소한의 조정만 했을 때 그 우위가 얼마나 오래갈지는 분명하지 않지만, 1~2주 안에는 알게 될 것 같습니다.
- @solarkraft — 좋은 시절이었습니다. 제가 가장 기억하는 예는 bottomless pit supervisor와, 비명을 지르는 뜨거운 수프를 생성하라는 요청을 받은 모델입니다.
원문: GitHub / 커뮤니티: Hacker News / 번역·요약: Trawling