dev.to

Kharcha: a 4B model that reads Indian bank SMS so the money stays on your laptop

Kharcha: 인도 은행 SMS를 읽는 4B 모델, 금융 정보는 노트북에 남깁니다

Kharcha는 인도 은행·UPI 문자와 Hinglish 메모를 가계부 항목으로 바꾸는 로컬 우선 지출 기록 도구입니다. 작성자는 Qwen3.5-4B를 LoRA로 미세 조정해 150개 테스트 메시지에서 전체 필드 일치율 97%를 얻었으며, 노트북에서 오프라인으로 실행하는 경로도 마련했습니다. 다만 노트북 실행 성능은 아직 측정하지 않았습니다.

AI 요약

Kharcha는 작성자의 어머니가 종이 가계부에 적던 지출을 정리하려고 만든 작은 장부입니다. 은행 SMS를 금융 앱에 맡기면 휴대전화 문자를 서버로 보내야 한다는 점을 피하고자, 메시지를 노트북에서 처리하는 방식을 택했습니다. 사용자는 인도 은행·UPI 알림을 붙여넣거나 “aaj sabzi wale ko 80 diye”처럼 자연어로 지출을 입력합니다. Qwen3.5-4B 기반 모델은 거래처, 금액, 계좌, 날짜, 분류 등을 JSON 한 줄로 만듭니다.

데이터셋과 학습

1,500건을 사람이 직접 라벨링하는 대신, 작성자는 HDFC, SBI, ICICI, Axis, Kotak, PNB 등 은행 문자 형식을 본뜬 26개 템플릿을 만들었습니다. 실제 상점 이름, 인도식 숫자 표기, 날짜 형식, VPA, 참조 번호와 Hinglish 음성 메모를 조합합니다. 메시지를 만든 프로그램이 정답 라벨도 함께 생성해 라벨을 정확히 맞췄습니다. 학습 데이터의 4분의 1은 잘림, 소문자화, 문장부호 제거 등 휴대전화에서 생길 법한 손상을 더했습니다.

데이터는 학습 1,200건, 검증 150건, 테스트 150건으로 나뉘며, 지출 분류는 12개입니다. 예시의 약 8분의 1에는 “Agarwal Sabzi Bhandar는 식료품으로 처리” 같은 사용자 규칙을 시스템 프롬프트에 넣었습니다. 모델이 기억 계층의 규칙을 따르도록 학습하기 위한 구성입니다.

작성자는 Thinking Machines의 Tinker에서 Qwen3.5-4B를 LoRA로 미세 조정했습니다. 어댑터 순위는 16이고, 3에폭 동안 111회 학습 단계를 실행해 약 110만 토큰을 처리했습니다. 손실은 JSON 출력 토큰에만 적용했으며 시스템 프롬프트와 SMS는 문맥으로 사용했습니다. 학습 비용은 1달러 미만이었고, 내보낸 어댑터 파일은 146MB입니다.

평가 결과와 한계

동일한 테스트 메시지 150건으로 기본 Qwen3.5-4B, gpt-oss-120b, 미세 조정한 Qwen3.5-4B를 비교했습니다. 전체 필드가 모두 일치한 비율은 각각 28%, 49%, 97%였습니다. 미세 조정 모델은 유효한 JSON, 금액, 거래처, 날짜, 분류에서 100%를 기록했습니다. 작성자는 남은 네 건이 “jooti ke 1200 lage”의 결제 수단을 현금으로 볼지 알 수 없는 채널로 볼지 정하는 문제였고, 정답 라벨 자체가 임의적이라고 설명합니다.

다만 수치 해석에는 주의가 필요합니다. 거래처 이름은 정답 표기 관례에 따라 달라질 수 있습니다. 예를 들어 큰 모델은 “ATM”이라고 썼지만 작성자의 라벨은 “SBI Bank ATM LAJPAT NAGAR”였습니다. 반면 분류는 표기 관례에 덜 좌우되며, 미세 조정 모델이 100%, 큰 모델이 81%를 기록했습니다. Tinker에서 측정한 지연 시간은 대기열 영향을 받아 모델 크기 비교에 적합하지 않습니다. 노트북에서 오프라인으로 실행했을 때의 속도는 아직 측정하지 않았습니다.

사용자 규칙이 포함된 테스트 메시지는 7건뿐입니다. 이 사례에서 기본 모델들은 규칙을 86% 따랐고, 미세 조정 모델은 모두 따랐습니다. 작성자는 이 결과를 기억 계층을 믿고 사용할 근거로 제시합니다. 다만 표본이 적으므로 이 비율은 해당 테스트 사례에 한정해 읽어야 합니다.

로컬 실행과 사용자 기억

앱은 FastAPI와 단일 HTML 페이지로 구성했습니다. 로컬에서는 Ollama를 호출하는 경로를 두었고, PARSER_BACKEND=ollama 설정으로 전환합니다. 어댑터를 GGUF로 변환하고 Ollama에 등록하는 코드도 마련했지만, 기본 모델 파일이 8GB라 작업 주말 안에 노트북 성능을 재지 못했습니다. 따라서 게시된 비교표는 Tinker 샘플링 API에서 실행한 결과입니다. 공개 데모 역시 무료 호스팅 환경에서 같은 어댑터를 제공하지만, 첫 실행에 약 1분이 걸리고 배포할 때마다 장부가 초기화됩니다.

가게 분류를 사용자가 고치면 Backboard에 “SHARMA KIRANA STORE는 식료품으로 처리” 같은 문장을 저장합니다. 다음 문자를 분석하기 전 원문으로 관련 기억을 검색하고, 실제 상점 이름이 메시지에 있을 때만 규칙을 프롬프트에 붙입니다. 기억의 저장과 검색에는 LLM을 넣지 않았습니다. 사용자는 기억을 목록으로 확인하거나 삭제할 수 있습니다.

월간 지출을 묻는 기능은 장부 요약과 관련 기억을 오픈 웨이트 모델에 전달합니다. 로컬에서는 Ollama의 Qwen3.5를 쓰고, 공개 데모에서는 Tinker의 Qwen3.5-9B를 사용합니다. 장부 요약이 장기 기억으로 저장되지 않도록 채팅 경로는 읽기 전용으로 바꿨습니다. 이 질문 응답 기능은 원문 SMS가 아니라 월간 요약만 다룹니다.

작성자가 강조한 설계 선택

작성자는 범위가 좁은 작업에서는 작은 모델을 특정 형식에 맞춰 미세 조정하는 편이 일반 모델보다 나은 결과를 낼 수 있다고 설명합니다. 또 사용자별 규칙을 모델 가중치에 숨기지 않고 읽을 수 있는 문장으로 저장합니다. 금융 문자를 외부 API로 보내지 않아도 되는 점이 이 프로젝트의 목적이며, 실제 노트북 오프라인 실행은 아직 성능 검증을 마치지 않았습니다.

dev.to 반응

  • @vamsi963601 — 설명이 인상적입니다, @itskumaryash. 어머니가 매일 쓸 앱으로 자리 잡기를 바랍니다. 몇 가지 궁금한 점이 있습니다. 어떤 모바일 기기에서 실행할 수 있나요? 이런 문제를 발견하고 시작하려면 AI 에이전트나 생성형 AI를 어느 정도 알아야 하나요?
  • @vivek_sharma_73c0c309b49e — 대단합니다!
  • @ben — 정말 멋지네요.
  • @axrisi — 안녕하세요. 미리 설정된 항목으로는 작동하는데, 여기서는 왜인지 실패하네요. 농담을 해보려 했는데 안 됐어요 😭😭😂
  • @hazemababneh — 좋네요!
  • @aimanfazal — 안녕하세요, 배지는 받으셨나요?

원문: dev.to / 번역·요약: Trawling