dev.to

Bank alerts to a day-book, with a local Gemma

은행 입금 알림을 장부로 바꾸는 로컬 Gemma

나이지리아 POS 운영자의 Moniepoint 입금 이메일을 일일 장부로 정리하는 웹 앱을 만들었습니다. 금액과 잔액은 코드로 처리하고, 은행마다 다르게 쓰는 고객 이름만 Gemma 3 1B로 읽습니다. 데이터는 기기에 남지만, 모델을 실행하려면 작동하는 GPU가 필요합니다.

에디터 노트

이 앱의 실용성은 이름 추출 정확도보다 실행 가능한 기기와 데이터 흐름에 달려 있습니다. 실제 알림 다섯 건에서 이름을 네 건 읽었고, 금액과 합계는 모델이 꺼져도 코드가 처리합니다. 다만 Mama POS 본인의 휴대전화는 GPU를 제공하지 않아 아직 앱을 직접 쓰지 못하며, 5,000나이라를 선불로 냈다는 사실도 실제 사용 검증과는 구분해야 합니다. 작은 표본과 제작자가 만든 합성 데이터라는 한계도 결과에 명시돼 있습니다. 댓글은 기술 논의가 아니라 계정 복구 광고입니다.

AI 요약

나이지리아 포트하코트에서 POS 단말기를 운영하는 Mama POS는 고객의 계좌이체를 확인한 뒤 현금을 내주고 수수료를 받습니다. Moniepoint 은행은 입금마다 이메일 알림을 보내지만, Mama POS는 내용을 공책에 옮기느라 시간이 오래 걸렸고 하루 수입을 맞추는 일도 그만뒀습니다. 고객이 돈을 보냈다고 말해도 입금이 확인되지 않는 일도 있었습니다. 제작자는 이 알림을 붙여 넣으면 자동으로 일일 장부를 만드는 웹 앱을 개발했습니다.

앱은 거래 시각과 금액, 입금 종류, 고객 이름을 표로 정리합니다. 사용자가 고객이 보냈다고 주장하는 금액을 입력하면 실제 입금 여부를 확인하고, 같은 금액의 거래가 두 건이면 이름 확인을 요청합니다. 하루가 끝나면 총입금액과 예상 수수료를 계산하고, 취소 거래나 10분 안에 반복된 같은 금액을 점검 목록에 올립니다. 사업주에게 WhatsApp으로 보낼 보고 문구도 만듭니다. 데이터는 서버로 전송하지 않고 브라우저 안에 둡니다.

코드와 모델의 역할

제작자는 코드가 처리할 수 있는 일은 코드에 맡기고, 모델은 코드로 해결하기 어려운 작업만 맡겼습니다. 이메일에 정해진 형식으로 들어 있는 금액과 시각, 잔액은 코드가 읽습니다. 입금 종류도 키워드 규칙으로 분류합니다. 고객 송금, 본인이 산 휴대전화 충전액인 airtime, 은행 보상금, 실패한 송금의 반환액을 구분합니다. 하루 합계와 수수료, 입금 확인도 코드로 계산합니다.

고객 이름은 은행마다 문구가 달라 규칙만으로 처리하기 어려웠습니다. 제작자는 입금 알림에서 이름이 'TRANSFER TO [고객] [은행]' 형태로 나올 것이라고 예상했습니다. 기존 키워드 규칙은 실제 알림 세 건에서 이름을 하나도 찾지 못했습니다. Gemma는 영상 촬영 당시 테스트에서 세 건 모두 이름을 찾았고, 앞선 테스트에서는 세 건 중 두 건을 찾았습니다. 한 알림은 내용 전체가 고객 이름뿐이라 모델이 놓쳤습니다.

이름 추출에는 브라우저에서 실행하는 Gemma 3 1B instruct의 ONNX q4 모델을 사용합니다. transformers.js와 WebGPU로 실행하며, 최초 실행 때 859MB를 내려받습니다. 이후에는 네트워크를 끈 상태에서 6초 만에 준비됐고, 노트북에서 이름 하나를 읽는 데 2~5초가 걸렸습니다. 모델 답변은 JSON이어야 하고, 거래 종류는 정해진 목록에서 골라야 합니다. 이름은 알림에 실제로 나온 글자여야 하며 문자가 포함돼야 합니다. 답변 속 숫자도 원문에 있어야 합니다. 이름 뒤에 붙은 은행명은 코드가 잘라냅니다. 검증에 실패하면 한 번 다시 시도하고, 그래도 실패하면 이름을 추측하지 않고 '읽지 못함'으로 둡니다. 모델이 꺼져 있거나 GPU가 중단돼도 금액과 시각, 종류를 기록하고 하루 합계를 계산하는 기능은 유지됩니다.

테스트와 실행 조건

Mama POS의 실제 알림 다섯 건에서는 거래 종류를 규칙이 5/5로 분류했고, 모델은 고객 이름을 4/5로 읽었습니다. 이름 점수에는 고객 이름이 없는 airtime과 cashback 알림도 포함됐습니다. 고객 송금 세 건만 보면 해당 테스트 실행에서 Gemma는 두 건을 맞혔습니다. 제작자가 만든 합성 알림 30건에서는 규칙이 종류를 30/30으로 분류하고 모델은 이름을 23/30으로 읽었습니다. 제작자는 규칙과 합성 데이터를 모두 직접 만들었으므로 이 결과를 공정한 종류 분류 점수로 보지 말아야 한다고 밝혔습니다. 실제 알림 테스트도 표본이 다섯 건뿐이며, 은행명 제거 규칙은 알림을 본 뒤 추가했습니다.

Mama POS의 Tecno Camon 17 Pro는 Android 11에서 WebGPU를 표시했지만 GPU 어댑터를 제공하지 않아 모델을 실행하지 못했습니다. CPU용 int8 모델은 제작자의 노트북에서도 30건 중 종류를 하나만 맞혔고, 알림마다 36초가 걸렸습니다. 앱은 지원되지 않는 휴대전화에서 1GB 안팎의 모델을 받기 전에 GPU가 필요하다고 안내합니다. 반면 제작자의 Pixel 8a에서는 Gemma가 기기에서 실행됐습니다. 4G 연결에서 다운로드가 멈춘 문제는 8MB 단위로 저장하고, 15초 동안 데이터가 오지 않는 조각을 재시도하며 중단 지점부터 이어받도록 고쳤습니다. GPU 장치가 실행 중 사라졌을 때 모든 행을 불명확 처리하던 동작도 바꿔, 첫 호출 실패 시 멈추고 앱을 다시 불러오도록 했습니다.

비용과 적용 범위

Mama POS는 앱을 위해 5,000나이라를 선불로 지불했지만 아직 직접 사용하지 않았습니다. 현재 휴대전화에서는 장부 기능만 쓸 수 있고 이름 추출에는 노트북이 필요합니다. 본인은 작동하는 GPU가 있는 새 휴대전화로 바꾸겠다고 했습니다. 모델은 사용자의 기기에서 실행되므로 알림과 잔액을 외부 API로 보낼 필요가 없고, 알림마다 API 비용도 들지 않습니다. 앱은 현재 Moniepoint 알림만 읽으며, Mama POS가 함께 쓰는 두 번째 POS 업체 Nomba의 알림은 지원하지 않습니다.

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

뉴스 타래

전체 보기

로컬 AI 도구의 역할 분담: 계산은 코드에, 해석은 모델에 맡길 때

세 사례는 모델을 어디에 쓸지 입력의 성격과 실패 비용에 맞춰 나눕니다. 정전 도구는 사실·수치를 코드로 만들고 Gemma에는 짧은 안내만 맡기며, 은행 장부는 이름 판독에만 모델을 씁니다. 음성 메모 도구도 모델별 역할을 분리하고 타임스탬프와 수치를 검증하지만, 배포·추론 방식과 검증 범위는 사례마다 다릅니다.