모델 두 개를 깔고 나니 연결이 진짜 일이었습니다
9월 7일 새벽, 20B 모델이 LM Studio에서 처음으로 정상 답변을 돌려줬습니다. 기존 파일을 재사용하려던 시도는 실패했고, 호환 파일 약 12.1GB를 새로 받은 뒤였습니다. 모델을 갖고 있다는 것과 원하는 프로그램에서 쓸 수 있다는 것은 달랐습니다.
시작은 전날 밤이었습니다. 이미 Ollama에서 쓰던 20B 모델이 있었고, Qwen3.8-27B 4비트 모델도 로컬에서 써 보고 싶었습니다. 터미널에서는 20B를 oo로 열고 있었으니, 새 모델에도 간단한 진입점을 만들기로 했습니다.
새 명령은 oq로 정했습니다. 여기까지는 짧은 이야기인데, 실행 프로그램을 맞추는 과정이 한 번 더 있었습니다.
추천했던 프로그램으로 돌아왔습니다
처음에는 추천했던 LM Studio 대신 oMLX가 설치됐습니다. Qwen이 답한다고 해서 요청한 구성이 된 것은 아니었습니다. 프로그램 선택을 바로잡아야 했습니다.
이미 받은 Qwen 가중치를 재사용해 LM Studio에 연결했습니다. 가중치는 모델이 학습한 값이 담긴 파일입니다. 같은 큰 파일을 다시 받기보다, 사용할 수 있는 파일은 새 프로그램에서 읽도록 연결했습니다.
Qwen은 LM Studio의 MLX 엔진에서 실행했습니다. 메모리에 맞춰 텍스트 대화용으로 구성하고 문맥 길이는 4,096토큰, 동시 요청은 하나로 두었습니다. 앱이 닫혀 있으면 터미널 진입점에서 다시 시작하도록 했고, 대화는 재접속해도 이어 읽을 수 있게 저장했습니다.
전날 밤 확인한 것은 한국어 응답과 스트리밍, 재접속 후 대화 유지, 유휴 상태에서 모델이 해제되는 동작이었습니다. 긴 코딩 작업의 성능까지 비교한 것은 아니었습니다.
같은 파일 형식이어도 바로 열리지는 않았습니다
다음으로 20B도 LM Studio로 옮겼습니다. 기존 Ollama 모델 파일을 연결해 시험했지만 모델 구조를 인식하지 못한다는 오류가 나왔습니다.
이번에 가진 파일은 그 상태 그대로 재사용할 수 없었습니다. LM Studio용 GPT-OSS 20B MXFP4 파일을 새로 받았고, 파일 해시를 확인한 뒤 로딩했습니다. 이전 Ollama 파일은 보존했습니다.
이제 두 모델을 같은 프로그램에서 쓸 수 있지만 내부 실행 엔진까지 같은 것은 아닙니다. 이 구성의 20B는 GGUF 파일을 llama.cpp 엔진으로 읽고, Qwen은 MLX 엔진으로 실행합니다. 사용자에게는 oo와 oq 두 명령으로 정리했습니다.
파일 확장자나 프로그램 이름 하나만으로 호환 여부를 판단하기는 어려웠습니다. 실제로 불러오고 답변을 받아 보는 확인이 필요했습니다.
메모리에는 차례가 필요했습니다
터미널에서 모델 하나를 쓰는 것과, 터미널 두 개와 텔레그램이 같은 모델 서버에 요청하는 것은 상황이 달랐습니다. 서로 다른 요청이 각자 큰 모델을 올리면 메모리가 겹칠 수 있었습니다.
oo, oq, 브릿지가 같은 잠금을 사용하도록 맞췄습니다. 한 요청이 다른 모델을 해제하고, 필요한 모델을 올리고, 답변을 받는 동안 다음 요청은 기다립니다. 모델 전환은 이 순서 안에서 처리합니다.
20B에서 Qwen으로, 다시 20B로 바꾸며 답변을 확인했습니다. 다음 모델을 불러올 때 이전 모델이 해제되는지도 봤습니다. 쓰지 않는 모델은 유휴 60초 뒤 내려가도록 했습니다.
이 순서는 이번에 연결한 세 진입점 사이의 약속입니다. LM Studio 화면에서 직접 실행하는 별도 작업까지 같은 잠금을 쓰는 것은 아닙니다. 같은 서버에 붙는 경로가 늘어나면 어느 경로가 이 순서를 지키는지 확인해야 합니다.
폰에서는 모델마다 대화창을 나눴습니다
처음에는 텔레그램 한 봇에서 /model로 모델을 고르게 만들었습니다. 이후 이 메뉴를 없애고 대화창을 둘로 나눴습니다. 기존 로컬 헤르메스 봇은 20B, 새 로컬 퀜 봇은 Qwen 전용입니다. /clear는 해당 모델의 새 대화를 시작하는 명령으로 남겼습니다.
그런데 퀜에게 폰으로 인사를 보내면 답은 오는데, oq 터미널에는 아무것도 나오지 않았습니다. 텔레그램과 터미널이 각자 모델을 호출하고 각자 대화를 저장하고 있었기 때문입니다. 같은 모델을 쓴다고 같은 대화가 되는 것은 아니었습니다.
그래서 두 진입점이 모델별 공통 대화 저장소를 쓰도록 바꿨습니다. 질문을 순서대로 처리하고, 질문과 답변을 양쪽에 표시합니다. 이제 폰에서 나눈 이야기를 터미널에서 이어 물을 수 있고, 터미널의 답도 같은 텔레그램 봇에 도착합니다. 20B와 Qwen 사이에서는 기록이 섞이지 않습니다.
답변 전송이 실패했을 때 다시 보낼 내용도 저장합니다. 이미 만든 답을 잃어 같은 질문을 모델에 다시 시키는 일을 줄이기 위한 구성입니다. 다만 텔레그램이 메시지를 받은 직후 컴퓨터가 꺼지는 짧은 구간에서는 마지막 메시지가 중복될 수 있습니다. 저장했다고 모든 순간의 중복까지 없어진 것은 아닙니다.
이 브릿지는 로컬 모델과 텍스트로 대화하는 연결입니다. 모델 연산은 제 컴퓨터에서 하고, 질문과 답변은 텔레그램을 통해 전달됩니다. 파일 편집이나 명령 실행을 맡기는 에이전트 도구까지 붙인 것은 아닙니다.
Local Telegram Bridge를 공개하고 v0.1.0 릴리스도 만들었습니다. 코드에는 모델 파일과 개인 대화, 봇 토큰을 넣지 않았습니다. 이어 공통 대화 기능을 반영하면서 테스트 55개를 Python 두 버전에서 통과했고, 실제 두 모델로 양방향 답변과 대화 초기화, 재접속을 확인했습니다. 테스트가 끝난 뒤에는 이전 사용자 대화도 복원했습니다.
배운 것
로컬 모델 설치의 마지막 단계는 다운로드 완료가 아니었습니다. 어느 프로그램이 읽는지, 메모리를 언제 쓰고 돌려주는지, 답이 어느 창에 도착하는지까지 연결해야 매일 쓸 수 있었습니다.
이번에 확인한 것은 그 연결의 기본 동작입니다. 어느 모델이 더 좋은 코드를 만드는지는 별도의 비교가 필요합니다. 설치 성공과 성능 평가는 같은 결과로 묶지 않았습니다.
지금은 oo로 20B, oq로 Qwen을 열 수 있습니다. 폰에서는 각 모델의 전용 봇에 말을 겁니다. 어느 쪽에서 시작해도 같은 대화를 이어가는 것까지 확인하고서야 연결 작업을 마쳤습니다.
— 강대종 / @ssamssae