LLM 로그확률로 이미지까지 분류하는 Jev 스타일 래퍼 공개

Hacker News15일 전조회 9

개발자 Allan이 LLM의 토큰 확률(logprob)을 읽어 분류기처럼 쓰는 Jev 스타일 요청 형식을 공개했다. 텍스트 상태만 다루던 기존 형식에 이미지 첨부를 위한 필드를 직접 덧붙였고, 웹캠 프레임을 받아 여러 질문에 한 번에 답하게 하는 파이썬 예제를 함께 실었다.

방식은 단순하다. 프롬프트에 상태와 질문, 그리고 선택지 목록을 제시한 뒤 "가장 적합한 보기의 글자 하나만 답하라"고 요구한다. 모델이 토큰 하나만 생성하므로 긴 서술이 나오지 않고 응답도 빠르다. 여기에 API가 함께 돌려주는 대체 토큰들의 로그확률을 정규화하면 각 선택지가 선택될 확률 분포를 얻을 수 있다. 질문 유형은 선택지 중 하나를 고르는 choice, 참일 확률을 뽑아내는 noul, 서수 점수를 기대값으로 계산하는 score 세 가지로 나뉜다.

비전 확장이 이 글의 핵심이다. Jev가 문서화한 요청 형식은 텍스트와 JSON 상태만 설명하고 있지만, 작성자는 attachments 필드를 추가해 base64 JPEG나 이미지 파일 경로를 한 번만 실어 보내고 여러 질문에 재사용하도록 했다. 웹캠 예제는 프레임을 받아 사람이 보이는지, 실내인지 실외인지, 장면이 얼마나 밝은지를 표로 출력한다. OpenCV는 웹캠 접근 편의를 위해서만 쓰였고 실제 컴퓨터 비전 처리는 하지 않는다.

성능 수치도 공개됐다. RTX 3090에서 Gemma 4 12B로 프레임당 세 개 질문을 돌리면 약 1 FPS가 나온다. 같은 예제를 OpenAI gpt-6-luna에 대해 실행하면 약 0.2 FPS로 떨어진다. 작성자는 프레임마다 질문마다 별도 연결이 발생하는 비용을 줄이려는 시도를 하지 않았기 때문이라고 짐작한다.

배경에는 Jev와 그 주변의 자체 호스팅 프로젝트들, 예컨대 OpenJev나 SemIf를 접하면서 알게 된 로그확률 읽기 기법이 있다. OpenAI의 logprobs 쿡북에도 나오는 오래된 요령이지만 작성자에게는 새로웠다고 한다. 같은 상태 접두어를 여러 질문이 공유하므로, 백엔드가 KV 캐싱을 지원하면 입력 처리 비용을 상당히 덜 수 있다는 점도 짚었다.

구현 세부도 눈에 띈다. OpenAI 쪽에서는 충분한 수의 대안 토큰을 받으려면 Responses API를 써야 하고, llama.cpp는 Chat Completions에서 로그확률을 돌려준다. 대안이 잘리지 않도록 top_p는 1로 둔다. 선택지는 질문당 2~20개로 제한되며 A부터 T까지 글자가 배정된다. API가 돌려주지 않은 선택지는 확률 0으로 처리하되, 누락분의 정규화 확률이 1e-6을 넘으면 오류로 간주해 조용히 틀린 결과가 나오는 것을 막는다.

실무적으로 흥미로운 지점은 유연성이다. 전용 컴퓨터 비전 모델이 훨씬 효율적이라는 점은 작성자도 인정한다. 그러나 이 방식은 판정 조건을 자연어로 서술하기만 하면 바뀐다. 재학습이나 모델 교체 없이 프롬프트 한 줄을 고쳐 새로운 분류 항목을 추가할 수 있다는 뜻이다. 상태 접두어를 KV 캐시로 공유하면 질문이 늘어나도 입력 처리 부담을 억제할 수 있다.

한계도 분명하다. 토큰 하나만 생성해도 입력을 읽는 시간은 그대로 든다. KV 캐싱은 백엔드가 지원할 때만 이점이 생긴다. API가 대안 토큰을 충분히 반환하지 않으면 확률 추정 자체가 무의미해진다. 초당 1프레임 수준의 처리량은 실시간 영상 분석 용도로 쓰기에는 부족한 편이다.

관련 글