2026년 10월 19일 월요일

Electric Objects EO1을 다시 살리는 사람들

Electric Objects EO1을 원래 서비스와 관계없이 활용하려는 시도는 이미 오래전부터 있었다. 이번에 EO1을 다시 사용해 보면서 특히 도움이 된 자료는 두 가지였다. 시간 순서로 보면 Darius Kazemi의 Hack Your EO1이 먼저이고, 그 뒤에 Christian Boyle의 eo1-workaround가 이어진다.

Hack Your EO1 — Darius Kazemi

먼저 참고한 것은 Darius Kazemi가 Feel Train 블로그에 2015년 9월 공개한 Hack Your EO1이다. 이 글은 EO1을 단순한 디지털 액자가 아니라 Android 4.4.2 KitKat이 돌아가는 하나의 컴퓨터로 바라본다.

EO1 뒷면의 micro-USB 단자에 OTG 어댑터와 USB 허브를 연결하여 키보드와 마우스를 사용할 수 있고, Windows 키와 B를 함께 누르면 Android의 기본 웹 브라우저를 실행할 수 있다는 매우 중요한 정보도 이 글에서 소개한다. 브라우저에서 APK를 내려받아 직접 설치하거나, Startup Manager를 이용하여 특정 앱을 부팅할 때 실행시키는 방법도 다룬다.

엊그제 EO1을 만지면서 OTG 허브에 키보드와 마우스를 연결하고 Win+B를 눌러 브라우저를 띄웠던 것도 바로 이 방법을 따른 것이다. 오래된 전자액자 안에 멀쩡한 Android 컴퓨터가 숨어 있다는 사실을 알려 준, 이번 작업의 출발점과 같은 글이었다.

참고: Darius Kazemi / Feel Train — Hack Your EO1

이 글은 Electric Objects의 서비스가 살아있던 시절 작성되었다. 당시에는 따라서 임의의 URL을 EO1으로 내보내는 것이 가능하였다. 그러나 지금은 다른 방법을 찾아야 하고, 몇 시간의 노력 끝에 성공하였다.

eo1-workaround — Christian Boyle

그 다음으로 직접적인 도움이 된 것은 Christian Boyle의 eo1-workaround이다. GitHub에 공개된 이 프로젝트는 제목 그대로 서비스가 중단된 EO1을 다시 사용할 수 있도록 하는 우회 방법을 제시한다.

여기에서도 EO1에 USB 허브와 키보드·마우스를 연결하고 Win+B로 기본 브라우저를 여는 방법을 사용한다. 그 다음 Firefox를 APK 형태로 내려받아 설치하고, 웹페이지를 이용하여 사진이나 이미지를 EO1 화면에 표시한다.

특히 흥미로웠던 것은 Firefox를 사용하는 이유였다. EO1에 들어 있는 오래된 Android 기본 브라우저보다는 Firefox가 Fullscreen API를 지원하기 때문에 브라우저의 메뉴나 주소창이 없는 디지털 액자다운 화면을 만들기에 유리하다.

실제로 이번 작업에서도 이 아이디어를 따라 구형 Android에서 동작하는 Firefox 68을 설치했다. Firefox의 홈페이지를 PC에서 실행하는 로컬 웹 서버 주소로 지정했더니 EO1을 껐다 켜도 그 설정이 유지되었다. 결국 Firefox는 이번 시스템의 실제 디스플레이 역할을 맡게 되었다.

참고: Christian Boyle / GitHub — eo1-workaround

두 프로젝트에서 나의 MetBoot까지

두 자료를 시간 순서와 역할로 놓고 보면 꽤 자연스럽게 연결된다. Darius Kazemi의 글이 EO1의 Android 내부로 들어가서 키보드, 마우스, 브라우저와 APK를 사용하는 기본적인 방법을 보여 주었다면, eo1-workaround는 그 방법을 이용하여 원래 Electric Objects 서비스가 사라진 뒤에도 EO1을 웹 기반 디지털 디스플레이로 사용하는 구체적인 방법을 보여 주었다.

이번에 내가 한 작업도 처음에는 거의 같은 길을 따라갔다. OTG 키보드와 마우스로 EO1에 접근하고, Win+B로 브라우저를 열고, APK를 sideload하고 Firefox를 설치했다.

다만 마지막 단계는 조금 달라졌다. The Metropolitan Museum of Art의 공개 작품을 PC에서 자동으로 내려받아 로컬 웹 서버로 제공하고, EO1에서는 Firefox로 그 페이지를 표시하도록 만들었다. 그리고 EO1이 켜지면 Firefox를 자동으로 실행시키기 위해 Android 4.4(API 19)에서 작동하는 아주 작은 앱인 MetBoot까지 직접 만들었다. 여기까지 오게 될 줄 누가 알았겠는가?

따라서 이 작은 프로젝트의 계보를 한 줄로 적는다면 다음과 같다.

Hack Your EO1 → eo1-workaround → MetBoot + The Met local gallery

처음에는 오래된 전자액자 하나를 다시 써 보자는 생각이었는데, 결국 OTG, Android 4.4, APK sideload, Firefox, Python 웹 서버, Android Studio까지 건드리게 되었다. 하지만 앞서 이런 기기를 열어 보고 기록을 남긴 사람들이 있었기에 가능한 일이었다.

2026년 10월 17일 토요일

Electric Objects EO1 전자액자를 되살려 보자

Electric Objects EO1이라는 전자액자를 우연한 기회에 구하여 잠깐 사용해 보았던 것이 2019년이다. 휴대폰 앱을 통해서 서버로 사진을 업로드하면 이를 와이파이로 접속한 상태에서 1080x1920의 세로 포맷의 이미지를 보여주던 물건이었다.


사진 출처는 내 블로그이다(링크). 잠깐 사용했던 초소형 푸시풀 진공관 앰프가 보인다. 

그 후 EO1에 대한 관심이 떨어져서 몇 년을 방치해 두었다가 다시 활용 가능성을 알아보기로 하였다. 이미 앱은 서비스가 되지 않는 상태였다. 전원을 넣어 보니 다음과 같이 접속 시도만 하는 상태이다.


2016년에 이를 용감하게 분해하여 정체를 알아 본 사람이 있었다(Electric Objects EO1 Digital Art Display Teardown). ARM 싱글보드 컴퓨터에 안드로이드가 설치되어 있으며, LCD 패널은 삼성전자 제품이고, 뒷면의 전원 어댑터 잭 바로 곁에 위치한 micro-USB가 USB OTG를 지원한다는 것까지를 확인하였다고 한다. ChatGPT에게 물어보니 OTG를 꽂아서 키보드를 연결한 뒤 Windows + B 버튼을 누르면 웹브라우저가 뜬다고 하였다. 서랍 속을 뒤지면 micro-USB OTG가 있지 않을까?


그렇다. 용케 필요한 물건을 이미 갖고 있는 것을 확인하였다. 그러나... 이것을 꽂으면 어댑터를 꽂을 수가 없다! 그래서 늦은 밤에 다이소에 가서 micro-USB <-> USB-C 젠더를 사 가지고 돌아왔다. USB type-C의 OTG는 갖고 있었기 때문. 하지만 이것으로는 키보드가 작동하지 않았다. 너무 여러 단계의 접속을 거쳐서 문제가 되는 것 같았다. NumLock, CapsLock을 아무리 눌러도 LED가 들어오지 않았다.

결국 위 사진의 것을 칼로 가공하여 커넥터 가까운 쪽에서 케이블을 꺾을 수 있게 만든 뒤 전원 어댑터를 꽂았다.


USB 키보드를 연결하니 CapsLock 키를 눌렀을 때 불이 들어온다. 그러면 키보드는 인식이 잘 된다는 뜻이다. Windows + B 키를 눌러 보았다. 



오! 가능성이 있다. 와이파이도 잘 인식된 상태였다. Ctrl + L을 눌러서 주소창에 네이버를 입력해 보았으나 보안 경고가 나왔다. 브라우저가 너무 오래된 것이 문제이다. HTTPS를 사용하지 않도록 만들어진 테스트용 사이트인 http://neverssl.com을 접속해 보니 다음과 같이 창이 열렸다. HTTPS가 아니라 HTTP여야 한다. USB 허브를 중간에 꽂으니 마우스 포인터도 나타났다.


세상을 향하여 창은 열려 있지만, EO1을 돌리는 구형 Android 브라우저가 현대 HTTPS/TLS와 호환되지 않는 것이 문제이다. 

자, 이 전자액자를 2026년 현재 어떻게 활용할 것인가? EO1의 LCD(삼성 LTM230HL07, 23인치, 1920x1080 PLS)에 맞는 컨트롤러를 구해서 LCD를 HDMI 모니터로 사용하는 것이 가능하다고 한다. 그러나 그렇게까지 침습적인 방법까지는 쓰고 싶지 않다. 

또 다른 가능성은 휴대폰이나 PC에서 웹서버를 띄운 뒤 EO1에서 접속하여 사진 디스플레이 등의 용도로 사용하는 것이다. 바이브 코딩으로 index.html과 이미지 일괄 리사이즈용 파이썬 스크립트를 만든 뒤, PC에서 로컬 웹서버를 실행하였다. 집 안의 동일한 와이파이 네트워크에서만 사용하는 것이므로 여기서는 HTTPS가 아닌 HTTP로 접속하도록 하였다. 다음은 EO1의 웹브라우저에서 PC의 웹서버에 정상적으로 접속이 됨을 확인한 화면이다.



구글 포토에서 최근에 찍은 사진을 몇 장 다운로드한 뒤 일괄 리사이즈 명령을 실행한 후 EO1에서 접속해 보았다. 성공이다!


좀 더 적극적인 활용 방법은 EO1에서 Linux를 구동하는 것이다. EO1은 ARM 기반의 i.MX6 프로세서를 사용하므로 적절한 Linux 이미지를 USB 메모리에 기록한 뒤, micro-USB OTG 허브를 통해 USB 메모리와 키보드 등을 연결하여 Linux로 부팅할 수 있다. 

이 방법은 실제로 EO1 사용자들이 시도한 바 있으며, 내장 Android를 지우지 않고 외부 USB에서 Linux를 실행할 수 있다는 점이 장점이다. Linux가 정상적으로 부팅되면 EO1은 더 이상 단순한 디지털 액자에 머물지 않고 SSH 접속, Python 프로그램 실행, 웹서버나 정보 대시보드 운영 등에 사용할 수 있는 작은 ARM Linux 컴퓨터가 된다. 다만 아무 ARM Linux 이미지나 사용할 수 있는 것은 아니며 EO1의 i.MX6 하드웨어에 맞는 부트로더와 커널을 갖춘 이미지가 필요하다. 이는 또 별도의 프로젝트가 될 것이다. 

메트로폴리탄 미술관 소장품 다운로드하여 디스플레이하기

EO1에 내가 찍은 사진만 띄우는 것도 좋지만, 디지털 액자라는 물건의 성격을 생각하면 미술관 소장품을 전시하는 용도로도 잘 어울린다. 뉴욕 메트로폴리탄 미술관(The Metropolitan Museum of Art, The Met)은 Public Domain에 해당하는 소장품 이미지와 메타데이터를 Open Access 정책에 따라 공개하고 있다.

The Met은 소장품 메타데이터 전체를 CSV 파일로도 제공한다. 이를 이용하여 Public Domain으로 표시된 회화 작품을 골라낸 뒤, 이미지가 제공되는 작품 중 100점을 무작위로 선택하여 다운로드하는 Python 스크립트를 만들었다.

처음에는 The Met의 Collection API를 이용하여 작품을 검색하려 했으나 검색 API가 HTTP 410(Gone)을 반환하였다. 그래서 Open Access 데이터셋인 MetObjects.csv를 내려받아 작품을 선별하고, 개별 작품의 이미지 주소를 얻는 데에만 API를 이용하는 방식으로 바꾸었다. CSV 파일은 처음 한 번만 내려받으면 된다.

다운로드한 이미지는 EO1 화면에 맞추어 1080 × 1920 픽셀로 변환하였다. 원본의 종횡비는 그대로 유지하고 남는 부분에는 검은 여백을 넣었다. 이렇게 만든 이미지 목록을 images.js에 기록하고, index.html에서 일정 시간 간격으로 무작위로 바뀌어 표시되도록 하였다.

마지막으로 이미지가 들어 있는 디렉터리에서 다음과 같이 간단한 웹서버를 실행하였다.

python -m http.server 8000

EO1과 PC가 같은 Wi-Fi에 연결되어 있다면 EO1의 웹브라우저에서 http://PC의-IP주소:8000으로 접속하면 된다. 집 안의 로컬 네트워크에서만 사용하는 것이므로 여기서는 HTTPS를 사용하지 않았다. 오히려 오래된 Android를 사용하는 EO1에서는 최신 HTTPS 사이트 접속에 문제가 있기 때문에 단순한 HTTP 서버가 편리하다.

결과적으로 별도의 앱을 설치하거나 EO1의 운영체제를 개조하지 않고도, 원래의 웹브라우저만 이용하여 The Met의 회화 작품을 차례로 보여주는 디지털 액자로 다시 사용할 수 있게 되었다. 서버 쪽의 이미지와 HTML을 바꾸면 EO1에서는 페이지를 다시 불러오는 것만으로 새로운 내용을 표시할 수 있다.

여가를 위한 프로젝트가 하나 더 늘어났다.

2026년 10월 11일 일요일

물건은 남는데 정보는 먼저 사라진다

이 글은 GitHub에 추가한 SyX2ool 프로젝트의 Background and Modification(BACKGROUND.md)을 국문으로 옮긴 것이다.

ChatGPT 자동 생성 이미지.

Korg X2와 SyX2ool을 만들게 된 이야기

Korg X2와 X3가 출시된 1990년대에는 3.5인치 플로피 디스크가 신시사이저와 컴퓨터 사이에서 데이터를 주고받는 평범한 수단이었다. 특히 내장 시퀀서를 갖춘 워크스테이션급 신시사이저에서 플로피 디스크 드라이브는 단순한 부가 기능이 아니었다. 곡과 시퀀스, 음색을 비롯한 사용자 데이터를 저장하고 다시 불러오는 중요한 장치였다.

30여 년이 지난 지금은 상황이 달라졌다. 신시사이저 본체는 여전히 멀쩡하게 작동하는데 플로피 디스크 드라이브가 먼저 고장 나는 일이 생긴다. 드라이브가 살아 있다고 해도 요즘 컴퓨터에서 플로피 디스크를 사용하는 것 자체가 매우 번거롭다.

한 가지 해결 방법은 원래의 플로피 디스크 드라이브를 Gotek 같은 플로피 에뮬레이터로 교체하는 것이다. 과거의 디스크 기반 작업 방식을 그대로 유지하려면 아마 이것이 가장 간단한 방법일 것이다. 그러나 나는 플로피 디스크 드라이브를 교체하지 않고 어디까지 할 수 있는지가 궁금했다.

플로피 디스크라는 통로를 제외하면 X2/X3와 현대의 컴퓨터를 이어 주는 가장 중요한 통로는 MIDI 포트가 된다. 일반 MIDI 메시지로 연주 정보를 주고받을 수 있고, System Exclusive(SysEx) 메시지를 이용하면 해당 신시사이저에 고유한 데이터까지 주고받을 수 있다.

이 과정에서 오래전에 만들어진 Java 프로그램인 X3File2Sysex가 큰 도움이 되었다. 다행히 예전에 보관해 둔 Korg 디스크 파일도 있었다. X3File2Sysex를 이용하면 디스크의 데이터(.PCG, .SNG)를 SysEx 형태로 바꾸어 MIDI를 통해 신시사이저로 전송할 수 있었다.

이것이 특히 중요했던 것은 X2의 내장 백업 배터리를 교체했을 때였다. 배터리를 교체한 뒤 X2를 다시 제대로 사용할 수 있는 상태로 만들려면 Preload Data 디스크의 데이터를 다시 올려야 했다. 그런데 플로피 디스크 드라이브가 고장 난 상태에서는 원래의 복구 방법을 사용할 수 없었다. X3File2Sysex와 MIDI 연결을 이용하니 필요한 디스크 데이터를 SysEx로 바꾸어 X2에 전송하는 방법으로 이 문제를 해결할 수 있었다.

이 경험을 통해 고장 난 플로피 디스크 드라이브를 우회하는 통로로 SysEx를 충분히 활용할 수 있다는 것을 알게 되었다. 그러나 기존 도구에는 한계도 있었다. 이미 준비된 데이터를 복원하는 것은 가능했지만, X2에서 덤프한 시퀀서 데이터를 자유롭게 들여다보고 수정하거나 다른 형식으로 바꾸어 다시 이용하는 것은 또 다른 문제였다.

오래전에 받아 둔 파일이 다시 귀중한 자료가 되다

지금 생각하면 정말 운이 좋았다. 아주 오래전에 어느 웹사이트에서 Korg X2/X3용 디스크 파일을 모아 놓은 ZIP 파일을 발견하여 받아 두었기 때문이다. 지금은 그 자료가 있던 웹사이트의 흔적조차 찾기가 쉽지 않다.

당시에는 그 파일을 보관해 둔 것이 특별히 중요하다고 생각하지 않았다. 그러나 수십 년이 지난 뒤 그것은 매우 귀중한 시험 자료가 되었다.

그 안에는 실제 Song과 User Pattern, Program, Drum 데이터 등 X2/X3에서 사용하던 여러 종류의 데이터가 들어 있었다. 이 파일들을 실제 X2에서 덤프한 SysEx 데이터와 비교하면서 막연한 추측이 아니라 실제 데이터를 바탕으로 내부 구조를 조사할 수 있었다.

또 하나 결정적으로 중요했던 자료는 Korg X2/X3 Reference Guide였다.

신시사이저를 단순히 연주하는 데에는 별로 눈에 띄지 않는 내용이 이 매뉴얼에는 상당히 자세하게 기록되어 있다. SysEx 명령, 시퀀서 파라미터, 이벤트의 종류, Pattern 관련 기능, MIDI 동작 등 내부 데이터 구조를 이해하는 데 필요한 기술적인 정보가 들어 있다.

물론 Reference Guide만 읽는다고 해서 시퀀서 덤프의 모든 바이트가 저절로 해석되는 것은 아니었다. 하지만 실제 SysEx 파일에서 발견되는 데이터를 이해하는 데 필요한 용어와 구조적인 단서를 제공했다.

결국 Reference Guide, 오래전에 보관해 둔 디스크 파일, X3File2Sysex, 그리고 실제 X2에서 얻은 덤프 데이터를 서로 비교하는 것이 X2/X3 시퀀서 형식을 분석하는 기반이 되었다.

그래서 SyX2ool을 만들기 시작했다

X2에서 시퀀서 데이터를 덤프하고, 기존 SysEx 데이터를 다시 X2로 보내는 것까지는 가능했다. 하지만 나는 덤프 파일을 정체를 알 수 없는 하나의 거대한 바이트 덩어리로 취급하는 데서 그치고 싶지 않았다.

그 안에 무엇이 들어 있는지를 알고 싶었다.

10개의 Song은 어디에 저장되어 있는가? 100개의 User Pattern은 어떤 구조로 들어 있는가? 각 Track과 Event는 어떻게 표현되는가? 그리고 X2/X3의 시퀀서 데이터와 오늘날에도 널리 사용하는 Standard MIDI File(SMF)을 서로 변환할 수는 없을까?

무엇보다도 플로피 디스크 드라이브에 의존하지 않고 현대의 컴퓨터에서 X2/X3의 내장 시퀀서에 좀 더 자유롭게 접근하고 싶었다.

그것이 SyX2ool을 만들게 된 동기였다.

SyX2ool이라는 이름은 SysEx + X2 + Tool을 합쳐 만든 것이다. 처음에는 X2/X3의 ALL SEQUENCE DATA 덤프를 해석해 보는 작은 실험으로 시작했다. 그러나 작업을 계속하면서 Song을 가져오고 내보내고, User Pattern을 추출하고, SysEx 데이터를 분석하고, MIDI와 Pattern 데이터를 실시간으로 신시사이저에서 연주하는 기능까지 갖춘 명령행 도구로 조금씩 발전하게 되었다.

그런 의미에서 SyX2ool은 X2/X3를 대신하기 위해 만든 프로그램이 아니다. 오히려 그 반대다.

오래된 X2/X3에서 원래 가지고 있던 기능을 오늘날에도 조금 더 자유롭게 사용할 수 있게 만드는 것이 목적이다.

하드웨어만 보존한다고 끝나는 것이 아니다

이번 작업을 하면서 또 하나 느낀 점이 있다.

오래된 신시사이저는 그것을 둘러싸고 있던 정보와 소프트웨어 생태계보다 오히려 더 오래 살아남을 수 있다는 것이다.

개인이 운영하던 웹사이트는 사라진다. 다운로드 링크는 끊어진다. 한때 유용했던 작은 프로그램은 더 이상 구하기 어려워진다. 사용자들 사이에서 공유되던 사용법과 기술적인 지식도 조금씩 사라진다.

내 컴퓨터 한구석에 별 생각 없이 보관해 두었던 오래된 파일들이 수십 년이 지난 뒤 X2/X3를 이해하는 데 매우 귀중한 자료가 되었다.

물건은 남는데, 정보는 먼저 사라진다.

SyX2ool 개발에는 이러한 정보의 일부라도 다시 기록하여 남겨 두려는 의미도 있다.


이 '덧붙임' 단락은 GitHub의 문서에는 포함되지 않았다.

덧붙임.1: 이 글을 쓰면서 X3File2Sysex를 지금도 인터넷에서 구할 수 있는지 찾아보았다. 한참 찾다 보니 뜻밖에도 내 오래된 홈페이지(My old synth and MIDI)에 x3file2sysex.zip을 올려 둔 흔적이 검색되었다. 올려 놓은 나 자신도 까맣게 잊고 있었다. 물건뿐 아니라 정보도, 때로는 어디에 보관했는지조차 잊은 채 살아남는다. 😄 


덧붙임.2: 한 시대를 풍미했던 MIDI 관련 MIDI-OX가 최신 Windows 컴퓨터에서 제대로 전송하지 못하는 SysEx를 놓고 얼마나 고민을 하였던가? 그러나 바이브 코딩으로 만든 Syx2ool 파이썬 스크립트는 X2의 설정 상태를 전부 덤프한 꽤 큰 용량의 SysEx 파일을 구렁이 담 넘어가듯 잘만 전송하였다. 

웹 서핑을 하다가 우연히 MIDI-OX의 개발자인 Jamie O'Connell의 자기 소개 정보를 접하였다(링크). 8년 동안 고단하고 힘든 밴드 생활을 하다가 소프트웨어 엔지니어가 되었다는 진솔한 이야기가 실려 있다. 이 웹사이트는 마지막 갱신일이 2003년 7월이다. 그의 GitHub 프로젝트 사이트에도 약간의 활동 내역이 있지만, 시간이 흐를수록 이런 역사적 자료는 점점 사라질 것이다.

2026년 10월 10일 토요일

X2 Piano는 살리고 X3DRUMS(시퀀스 및 패턴)는 제대로 올리기 — SysEx 파일을 AI로 고쳐 쓰다

Korg X2는 90년대의 Pop & Rock의 표준적인 음색과 나쁘지 않은 이펙터를 내장하고 있다. 내가 특별히 관심을 두고 있는 것은 내장 시퀀서와 드럼 패턴이다. 인터넷에서 구한 XSD-15 Power Disk라는 프리셋 디스크의 내용물 중에 X3DRUMS.SNG에는 음악 제작이나 라이브에서 재사용 가능한 패턴 100개가 장르별로 10개의 곡에 채워져서 제공된다. 실제 소리가 궁금하다면 내가 1년 전에 올린 다음 영상을 확인하면 된다.



하지만 X2 기본 설정 상태에서 이 SNG 데이터만 로드하면 제 소리가 나지 않는다. 실제로는 플로피 디스크 드라이브가 망가진 상태라서 SNG 파일을 직접 로드할 수는 없고, 이를 SysEx로 전환한 것을 사용하고 있다. 제 소리를 내려면 Song/Pattern 데이터뿐 아니라 X3DRUMS에 맞는 Program과 Drum Kit 데이터도 함께 로드해야 한다. 내가 사용하는 SysEx 파일로 말하면 X3DRUMS_Prog.syx와 X3DRUMS_Drums.syx가 그것이다. 이렇게 하였을 때 가장 큰 불편함은 X2의 최대 장점인 Program A01 "X2 Piano"가 사라진다는 것이다. 매뉴얼을 참고하여 A01을 X2의 것으로 고쳐 놓으면 되지만 여간 불편한 것이 아니다. Multisound를 340번 피아노로 맞추는 것 외에도 이펙터를 비롯한 여러 설정을 손봐야 하니 여간 번거로운 일이 아니다. 이러한 불편함은 인공지능 덕분에 크게 줄어들게 되었다. 매뉴얼과 샘플 파일을 밀어 넣고 원하는 사항을 지시하면 되기 때문이다.

  • X2: A01 = X2 Piano, B01 = Piano 16' 
  • X3: A01 = Piano 8', B02 = ExpressoPF

X2/X3에는 편집 가능한 4개의 드럼킷(A1/A2/B1/B2)과 8개의 ROM 드럼킷이 있다. 이 4개의 드럼킷에서 각 키(건반)에 어떤 Drum Sound를 배치하고 어떻게 소리 나게 할 것인지는 Drums.syx에 저장된다. 반면 각 Drum Program이 이들 가운데 어느 Drum Kit을 사용할 것인지는 Prog.syx에 저장된다. 따라서 X3DRUMS의 song 및 사용자 패턴을 제작자가 의도한 음색으로 재생하려면 X3DRUMS_Prog.syx와 X3DRUMS_Drums.syx를 모두 로드해야 한다. 

놀랍게도 X2/X3의 기본 설정에서 B1은 프로그램에 할당되어 있지 않다. 

  • Program A09 (Total Kit) => A1 (Total Kit)
  • Program A69 (ProdcrKit) => A2 (Producer Kit)
  • Program B09 (Rave Kit) => B2 (Rave Kit)
  • Program B69 (VeloGated) => B2 (Rave Kit)

처음에는 이 결과가 잘 이해되지 않았다. 혹시 설정이 변형된 장비에서 덤프한 SysEx 파일을 표준 데이터처럼 사용하고 있는 것은 아닐까 하는 의심도 들었다. 그러나 X2에 Preload 데이터를 다시 로드한 뒤 실제 Program Edit 화면에서 확인해도 B09와 B69는 모두 B2를 사용하고 있었고, 별도로 살펴본 X3 Preload의 Program 데이터에서도 같은 관계가 확인되었다. 따라서 B1이 기본 Drum Program에서 사용되지 않는 것은 단순한 덤프 오류라기보다는 원래 그렇게 설계된 것으로 보인다.

그러나 X3DRUMS의 Program 데이터를 그대로 로드하면 X2의 Piano인 Program A01도 X3DRUMS의 A01로 덮어써진다. X2 Piano를 계속 사용하고 싶었기 때문에, X3DRUMS의 Program 데이터는 그대로 유지하면서 A01만 X2 Preload의 Piano 설정으로 교체하도록 ChatGPT에 지시하였다. 이렇게 만든 수정 SysEx를 사용하면 X3DRUMS에 필요한 Drum Program 설정을 유지하면서 X2의 A01 Piano도 함께 사용할 수 있다.

X3DRUMS User Pattern 목록
Song 제목 Pattern 길이 프리뷰용 Program / Drum Kit
S6 Rock&Roll! P00–P19 모두 2 bar A09 Total Kit / A1
S0 16 Beat P20–P29 모두 2 bar A09 Total Kit / A1
S9 Waltz1,2,3 P30–P35 모두 2 bar A09 Total Kit / A1
S7 Shuffels P36–P43 모두 2 bar A09 Total Kit / A1
S3* Latin&Perc P44–P59 모두 1 bar B69 Percussion / B1
S1* CntryPolka P60–P69 모두 1 bar B69 Percussion / B1
S2* Dance !!! P70–P79 모두 1 bar B09 Rave Kit / B2
S5* Rap!!! P80–P89 P80–85: 2 bar / P86–89: 1 bar B09 Rave Kit / B2
S4* Rap Filler P90–P94 모두 1 bar B09 Rave Kit / B2
S8 Slow Jams P95–P99 모두 1 bar A09 Total Kit / A1

* X2/X3 Preload 상태에서 X3DRUMS의 Song/Pattern 데이터만 로드하면 원래 의도한 음색으로 재생되지 않는 곡.

X3DRUMS에서 확인한 중요한 변경은 다음과 같다.

  • 기본 Preload에서는 사용되지 않던 B1 (Percussion Kit)을 Program B69가 사용하도록 변경하였다. B1 자체의 내용은 Preload와 동일하며, B69의 이름은 VeloGated에서 Percussion으로 바뀌었다.
  • B2 (Rave Kit)는 X3DRUMS에서 Drum Kit 자체의 내용이 대폭 변경되었다.

결론적으로 X2의 장점인 X2 Piano를 유지하면서 X3DRUMS의 드럼 패턴과 시퀀스를 원래 의도된 소리로 사용하는 방법은 다음과 같다.

  1. X2 Preload를 기본 상태로 삼는다.
  2. X3DRUMS_Drums.syx와 X3DRUMS의 Song/Pattern 데이터를 전송한다.
  3. X3DRUMS_Prog.syx에서 Program A01만 X2 Preload의 X2 Piano로 치환한 수정 SysEx를 전송한다. 이 파일은 두 Program dump를 ChatGPT에 주고 A01 데이터만 교체하도록 지시하여 만들었다.

X3DRUMS의 시퀀스 덤프에서 패턴 데이터를 풀어낸다고 해서 곧바로 표준 MIDI처럼 사용할 수 있는 것은 아니다. PC에서 MIDI 케이블을 통해 X2로 드럼 연주 정보를 보내려면 패턴 내부의 이벤트와 시간 정보가 실제 MIDI 메시지로 어떻게 대응되는지를 더 알아내야 한다. 특히 라이브 드럼머신처럼 PC에서 다음 패턴을 즉석에서 예약하고, 현재 패턴이 끝나는 다음 bar부터 정확히 전환하여 연주하려면 PC 쪽에서 패턴의 재생과 타이밍을 직접 관리해야 한다. X2에 저장된 User Pattern을 외부 MIDI에서 이런 방식으로 선택하고 전환하는 기능은 매뉴얼에서는 확인되지 않기 때문이다.

어휴, 차라리 이런 물건 갖고 노는 것이 정신 건강에 더 이롭지 않을까?


정신 건강에는 이런 물건이 낫고, 지적 유희에는 X2가 낫다. Ardule 드럼 패턴학 생태계까지 X2를 이어 보려는 것이 나의 장기적 목표이다.

신시사이저 역사에서 Korg X2/X3가 갖는 의미

Korg X2/X3는 신시사이저 역사에서 M1이나 Trinity, Triton처럼 새로운 시대를 연 기종은 아니다. 그러나 1980년대 말부터 1990년대 중반까지 이어진 Korg 워크스테이션의 발전 과정을 이해하기에는 꽤 흥미로운 악기이다.

요즘 두 기기의 '케미'가 아주 좋다. USB 케이블 형태의 MIDI 인터페이스는 '대용량' SysEx 전송에서 동작 불안정으로 인해 서랍 속으로 들어가 버렸다.

1988년에 등장한 M1은 PCM 기반 음원, 디지털 이펙트, 드럼과 시퀀서를 한 악기에 통합하면서 이른바 ‘뮤직 워크스테이션’이라는 악기 유형을 대중화했다. Korg 역시 M1이 워크스테이션이라는 새로운 악기 범주를 정의한 제품이라고 평가한다. 이후 T 시리즈를 거쳐 1991년에는 AI² 음원과 waveshaping을 채택한 01/W 시리즈가 등장했다.

X3는 1993년에 출시되었다. 내가 보유한 X2는 그 이듬해 등장한 76건반 모델(피아노 음색이 강화됨)이며, 2004년 3월에 천안 백석대학교 근처까지 가서 중고품을 구입하였다. 이들은 앞선 Korg 워크스테이션에서 발전해 온 AI² 계열의 PCM 음원 기술을 계승했다. X3의 경우 340개의 PCM multisound, 32음 동시발음, 두 개의 디지털 multi-effect processor, 16트랙 시퀀서와 32,000 event의 기록 용량을 갖추었다. 시퀀서에는 10개의 Song과 100개의 Pattern을 저장할 수 있었으며, 3.5인치 플로피디스크와 Standard MIDI File(SMF), General MIDI도 지원했다.

그러나 X2/X3가 기술적으로 새로운 시대를 연 것은 아니었다. 오히려 이미 상당히 성숙한 Korg의 PCM 워크스테이션 기술을 보다 실용적인 형태로 정리한 제품에 가까웠다. 01/W에 있었던 waveshaping도 X3에서는 사라졌다. 당시의 평가에서도 X3는 획기적인 신기술을 선보인 악기라기보다 기존 AI² 기술을 이용하여 가격과 기능의 균형을 맞춘 워크스테이션으로 받아들여졌다.

이 점은 전후의 Korg 제품을 함께 보면 더욱 분명해진다. X3보다 5년 앞선 1988년에는 역사적인 M1이 있었고, 1990년에는 독특한 Wave Sequencing과 Vector Synthesis를 내세운 Wavestation이 등장했다. 그리고 X2가 나온 바로 다음 해인 1995년에는 Trinity가 등장했다. Trinity는 터치스크린 기반의 TouchView 인터페이스와 당시로서는 고품질·대용량인 PCM, 다양한 확장 기능을 갖춘 새로운 세대의 플래그십 워크스테이션이었다. 1999년에는 그 계보를 이어 Triton이 등장했다.

따라서 Korg 워크스테이션의 역사를 아주 단순화한다면 다음과 같은 두 시대를 생각해 볼 수 있다.

M1 → T series → 01/W → X2/X3
      ↓
Trinity → Triton → 이후 세대

물론 이것은 엄밀한 제품 계보도가 아니라 기술과 제품 성격의 변화를 이해하기 위한 단순화이다. X2/X3 이후에도 AI² 계열 제품은 계속 출시되었다.

그렇다면 X2/X3의 역사적 가치는 무엇일까?

이 악기에는 1990년대 초반의 ‘워크스테이션’이라는 개념이 매우 전형적인 형태로 남아 있다. 컴퓨터를 사용하지 않고도 한 대의 건반악기에서 음색을 고르고 Combination을 만들고, 드럼 Pattern을 구성하고, 16트랙 Sequencer에 곡을 녹음한 뒤 플로피디스크에 저장한다. MIDI와 SysEx를 이용해 외부 기기와 데이터를 주고받고, GM/SMF를 통해 다른 환경에서 만들어진 곡을 재생할 수도 있다.

오늘날의 DAW 중심 작업 환경에서 보면 번거로운 방식이다. 하지만 바로 그렇기 때문에 X2/X3를 직접 사용해 보는 것은 1990년대 초반의 전자악기가 지향했던 ‘컴퓨터 없이 한 대에서 곡 전체를 만드는 작업 환경’을 경험하는 일이기도 하다.

X2/X3는 Korg 역사에서 가장 유명하거나 가장 혁신적인 신시사이저는 아니다. 오히려 M1에서 시작된 초기 PCM 워크스테이션 시대가 충분히 성숙한 시점에 등장한 실용적인 제품이라고 보는 편이 적절하다. 그리고 바로 다음 해 Trinity가 등장하면서 Korg의 워크스테이션은 새로운 세대로 넘어가기 시작했다.

그런 의미에서 X2는 ‘명기’라는 하기 어렵다. 그러나 한 시대의 기술과 음악 제작 방식을 잘 보존하고 있는 흥미로운 악기라고 부르는 편이 더 어울린다.

그러면 나는 2026년에 이르러 왜 이렇게 낡은 신시사이저인 X2에 집착하는가? 가장 큰 출발점은 아마도 일종의 ‘죄책감’이었을 것이다. 22년 전 결코 적지 않은 돈을 주고 중고로 구입했으면서도 제대로 활용하지 못한 채 오랫동안 방치해 두었다. 그동안 피아노 대용의 연습 악기로라도 꾸준히 사용했다면 지금쯤 내 연주 실력이 훨씬 나아졌으리라는 것은 자명하다.

두 번째 이유는 X2가 나의 DIY적 호기심을 자극하기 때문이다. 오래된 전자악기인 만큼 유지보수와 수리가 필요하고, 때로는 직접 개선해 볼 여지도 있다. 뜯어보고, 고치고, 데이터를 들여다보고, 원하는 기능을 만들어 보기에 아주 적당한 대상이다. 더구나 인공지능의 발전으로 과거의 나로서는 엄두를 내기 어려웠던 SysEx 분석이나 프로그래밍까지 직접 시도할 수 있게 되었다.

처음 다시 X2를 만지기 시작했을 때는 첫 번째 이유가 더 컸는지도 모르겠다. 하지만 지금은 분명히 두 번째 이유가 더 크다. X2는 이제 연주해야 할 오래된 악기인 동시에, 가지고 놀기에 아주 재미있는 오래된 기계가 되었다.

2026년 10월 6일 화요일

[KORG X2] 30년 된 신시사이저의 시퀀서 포맷을 파헤치다

집에 있는 Korg X2는 1990년대 초에 나온 신시사이저이다. USB 같은 것은 당연히 없고 데이터를 주고받으려면 플로피디스크나 MIDI를 이용해야 한다. 최근 고장 난 플로피 드라이브를 Gotek(USB 메모리를 이용하는 에뮬레이터)으로 바꿀까 고민하다가 엉뚱한 생각이 들었다. PC에 있는 MIDI 파일을 X2의 내장 시퀀서에 직접 집어넣을 수는 없을까?

PC에서 MIDI 파일을 재생하면서 X2를 음원으로 사용하는 것은 간단하다. 내가 해 보려는 것은 그것이 아니라 Standard MIDI File(SMF)을 X2의 시퀀서 데이터로 변환하여 SysEx로 보내는 것이었다.

다행히 X2/X3 Reference Guide에는 MIDI implementation이 꽤 자세히 나와 있다. X2의 시퀀서는 10개의 Song(S0~S9)과 100개의 User Pattern(P00~P99)을 저장할 수 있으며, 이것을 ALL SEQUENCE DATA라는 하나의 SysEx로 덤프할 수 있다. 실제 덤프를 풀어 보니 control data 뒤에 4 byte 단위의 Note, Program Change, Control Change, Pitch Bend 등의 event가 이어진다. 그렇다면 MIDI 파일의 event를 이것으로 바꾸어 SysEx로 전환하여 주면 될 것 같았다. GM 전용으로 할당된 S9를 목적지로 해야 한다.

시험곡은 Olivia Newton-John의 Physical이었다. 결코 쉽지는 않았다. 특히 velocity를 잘못 해석한 버전에서는 음이 거의 나오지 않고 틱틱 강하게 튀는 소리만 났다. 매뉴얼과 실제 dump를 다시 비교하여 고친 뒤 전송하니 드디어 X2의 S9에서 Physical이 제대로 연주되었다. 124 BPM도 정확했다. tempo를 달리 설정하여 받은 dump들을 비교해 보니 실제 저장값은 BPM - 30이라는 것도 알게 되었다. 다음은 MIDI 파일을 SysEx로 전환하여 X2로 전송하여 시퀀서의 S9 영역에 넣은 다음 재생하는 모습을 촬영하는 것이다. 오디오와 비디오를 따로 기록한 뒤 합치는 바람에 싱크가 썩 잘 맞지는 않는다.



처음에는 변환할 때 X2에서 받아 놓은 기존 sequence dump를 template으로 사용했다. 그런데 생각해 보니 굳이 그럴 필요가 없었다. X2에는 전원을 켤 때 S0~S9과 P00~P99를 모두 지우는 기능이 있다. 그렇게 완전히 비운 뒤 바로 dump를 받으니 4,240 byte짜리 아주 작은 SysEx가 생겼다. X2 자신이 만들어 준 빈 시퀀서인 셈이다. 이것을 converter 안에 넣어 버렸다. 이제 MIDI 파일 하나만 주면 빈 X2 시퀀서를 만들고 S9에 곡을 채워 넣을 수 있다. 기존 dump를 template으로 주면 S0~S8과 Pattern은 그대로 두고 S9만 바꾸어 준다.

중간에 MIDI 전송 때문에 엉뚱한 곳에서 고생하기도 했다. 싸구려 USB-MIDI 케이블로 큰 SysEx를 보내면 MIDI-OX에서는 끝났다고 하는데 X2는 계속 Processing... 상태에 머물렀다. Mackie Onyx Producer 2•2의 MIDI 인터페이스 기능을 사용하자 문제가 사라졌다. 현재 MIDI-OX에서는 input buffer 256 bytes × 32, output buffer 1024 bytes × 128, Auto-adjust Buffer Delays를 켜 놓고 사용한다.



SysEx의 크기가 40KB 정도 넘어가면 버퍼가 부족하다는 에러 메시지가 자꾸 나와서 애를 먹었다. 그 원인으로서 Windows의 새로운 MIDI Server 기능도 의심했다. 그래서 관리자 권한으로 PowerShell을 열고 다음 명령을 실행하여 기존 Legacy MIDI 방식을 사용하도록 설정한 뒤 Windows를 재부팅했다.

reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32" /v UseLegacyMidi /t REG_DWORD /d 1 /f

재부팅 뒤에는 다음 명령으로 MidiSrv.exe가 실행되고 있는지 확인했다. 단, 재부팅 직후에는 보이지 않을 수 있다. 새 MIDI 서비스를 사용하는 프로그램이나 장치가 서비스를 요청하였을 때에만 tasklist에 보이는 것이 기본이라 한다. 

tasklist | findstr /I MidiSrv 

아무것도 출력되지 않는 것을 확인했다. 적어도 이 상태에서는 MidiSrv.exe가 실행되고 있지 않았다. 원래 설정으로 되돌리려면 같은 레지스트리 값을 0으로 바꾸고 다시 재부팅하면 된다.

reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32" /v UseLegacyMidi /t REG_DWORD /d 0 /f

다만 이것이 SysEx 전송 문제를 해결한 결정적인 조치였다고 보기는 어렵다. 나중에 USB-MIDI 케이블 대신 Mackie Onyx Producer 2•2의 MIDI 단자를 사용하자 전송이 안정되었기 때문이다. 따라서 당시 문제의 원인은 Windows MIDI Services보다는 사용하던 USB-MIDI 인터페이스였을 가능성이 더 크다.

지금 프로그램 이름은 midi_to_korg_x2_s9_v6_1.py이다. 너무 길다. 앞으로는 이름을 SyX2ool이라고 바꾸어 볼 생각이다. 이는 SYX + X2 + Tool의 합성어이자 말장난이다. 향후 다음과 같은 subcommand 방식으로 개발을 완결할 것이다.

예:

syx2ool import
syx2ool export
syx2ool analyze
syx2ool compare

아직 할 일이 있다. 지금은 MIDI 파일을 X2의 S9으로 보내는 방향이 중심인데, 다음에는 반대로 X2에서 받은 sequence dump의 S0~S8을 각각 SMF Format 1으로 변환해 보려고 한다. User Pattern을 사용한 부분은 실제 MIDI event로 풀어내야 하므로 조금 더 분석이 필요하다. 이것까지 되면 MIDI → X2 SysEx → MIDI의 왕복 변환도 시험할 수 있다.

이 정도면 리버스 엔지니어링이라고 거창하게 부를 일은 아니다. Korg가 옛날 매뉴얼에 자료를 상당히 잘 남겨 놓았다. 매뉴얼을 읽고, X2가 내놓는 byte를 비교하고, 프로그램을 고쳐서 다시 집어넣어 보는 일을 반복했을 뿐이다. 이 과정에서 ChatGPT의 도움을 많이 받았다.

그래도 30년 넘은 신시사이저가 내가 만든 데이터로 Physical을 연주하기 시작했을 때는 꽤 재미있었다. 이래서 오래된 기계를 쉽게 버리지 못한다.


2026년 10월 5일 월요일

[KORG X2] 오후 내내 RAG를 만지작거리다가 원래 자리로 돌아왔다

오늘 오전에는 Korg X2/X3 매뉴얼을 좀 더 편하게 찾아보기 위한 작은 프로그램을 만들었다(원본 글). 가지고 있는 매뉴얼 PDF는 오래된 스캔 자료라서 텍스트를 직접 검색할 수 없다. 우선 OCR을 거쳐 각 페이지의 글자를 추출하고, 어느 매뉴얼의 몇 번째 PDF 페이지에서 나온 글인지 알 수 있도록 JSON 파일로 정리하였다. 여기에 Ollama에서 로컬로 실행하는 qwen3:1.7b를 이용하여 한국어 질문을 검색에 적합한 영어 표현으로 바꾸고, 관련성이 높은 매뉴얼 페이지를 찾아주는 기능을 붙였다. 검색된 페이지는 원래 PDF의 모습 그대로 화면에서 볼 수 있게 하였다.

처음에는 검색된 내용을 다시 언어모델에 넘겨 질문에 대한 답까지 만들어 보기도 했다. 그런데 여기에서 작은 문제가 발견되었다. 검색된 원문에는 없는 용어나 수치를 언어모델이 그럴듯하게 만들어 답에 섞는 일이 있었다. 오래된 신시사이저의 사용법을 알아보려고 매뉴얼을 찾는 것인데, 없는 기능을 AI가 만들어내면 곤란하다. 그래서 AI가 답을 대신 써 주게 하는 것보다 관련된 원문 페이지를 잘 찾아서 내가 직접 읽는 것이 이 용도에는 더 안전하겠다는 생각이 들었다.

그렇게 해서 오전 작업의 결과물은 거창한 AI 챗봇이라기보다는 일종의 지능형 매뉴얼 검색기에 가까워졌다. 한국어로 질문하면 관련성이 높은 페이지 몇 개를 제시하고, 그중 하나를 선택하면 실제 매뉴얼 페이지를 보여준다. Basic Guide와 Reference Guide의 목차를 이용해서 직접 찾아 들어갈 수도 있다. 인터넷 연결도 필요 없고 API 사용료도 들지 않는다. 드럼 키트의 편집 위치나 snare drum의 pitch 조정처럼 구체적인 질문에는 꽤 쓸 만한 페이지를 찾아 주었다. 여기까지만 해도 처음 원했던 것은 거의 이루어진 셈이었다.

그런데 오후가 되자 욕심이 생겼다. 예를 들어 “왼손으로는 베이스, 오른손으로는 피아노를 연주하려면 어떻게 하나?”와 같은 질문을 생각해 보았다. 사람이라면 이것이 건반을 두 영역으로 나누는 split 설정에 관한 질문이라는 것을 쉽게 알아듣는다. Korg X2의 구조를 조금 아는 사람이라면 Combination에서 각 Timbre의 Key Window를 설정하는 부분을 찾아야 한다는 것도 짐작할 수 있다. 그러나 작은 언어모델과 단순한 검색의 조합은 반드시 그렇게 생각하지 않았다.

여기에서 오후의 삽질이 시작되었다. 요즘 문서 기반 AI를 이야기하면 빠지지 않고 등장하는 것이 RAG(Retrieval-Augmented Generation), 즉 검색 증강 생성이다. 오전에 만든 프로그램도 넓게 보면 검색한 원문을 언어모델과 연결한다는 점에서 아주 단순한 RAG라고 할 수 있다. 그렇다면 조금 더 제대로 된 RAG 방식을 적용하면 검색 성능이 좋아지지 않을까 하는 생각이 들었다.

우선 페이지 전체를 검색 단위로 삼는 것이 문제일 수 있다고 생각하여 매뉴얼의 OCR 텍스트를 작은 덩어리, 즉 chunk로 나누었다. Basic Guide와 Reference Guide를 합쳐 모두 609개의 chunk가 만들어졌다. 결과를 직접 살펴보니 나누어진 모양 자체는 제법 괜찮았다. Split과 관련된 Key Window 설명도 적절한 덩어리로 잡혔고, snare drum의 Tune이나 tempo 설정에 관한 설명도 잘 나뉘어 있었다.

다음에는 각 chunk의 의미를 숫자로 표현하는 embedding을 만들었다. Ollama에서 nomic-embed-text 모델을 사용하였다. 609개의 chunk를 모두 embedding하는 데 내 노트북에서 약 249초가 걸렸다. 질문도 같은 방법으로 벡터로 만들면 단어가 정확하게 일치하지 않더라도 의미가 비슷한 설명을 찾을 수 있을 것이라고 기대하였다.

여기에 CrossEncoder라는 것도 동원하였다. embedding 검색으로 우선 후보를 뽑고, 질문과 각각의 후보를 다시 함께 비교하여 관련성을 좀 더 정밀하게 평가하는 reranking 방식이다. 문서 검색에서는 이미 널리 사용되는 전형적인 2단계 구조라고 한다. 처음에는 609개 chunk를 전부 CrossEncoder로 비교해 보았는데 너무 느렸고, 그래서 embedding으로 상위 20개 후보를 먼저 고른 뒤 그 후보만 다시 순위를 매기는 방식으로 바꾸었다. 어느새 오래된 신시사이저 매뉴얼을 좀 편하게 읽겠다는 일이 작은 정보검색 실험으로 변하고 있었다.

결과는 흥미로웠다. Snare pitch나 tempo처럼 질문과 매뉴얼의 용어가 비교적 잘 대응하는 경우에는 아주 잘 작동하였다. 정답에 해당하는 chunk가 embedding 검색에서 처음부터 1위에 들어왔고 reranking을 거친 뒤에도 1위를 유지하였다. 하지만 정작 개선하고 싶었던 split 질문은 그렇지 않았다. 관련된 Key Window chunk 하나가 embedding 검색 후보 16위에 겨우 들어왔고 reranking 뒤에는 5위가 되었다. 더 직접적으로 관련된 다른 chunk는 상위 20개 후보에도 들어오지 못했다. 엉뚱한 effect 관련 설명이 최종 1위를 차지하는 경우도 있었다.

검색 한 번에는 3초 남짓이 걸렸다. 오전에 만든 단순한 검색보다 구조는 훨씬 복잡해졌지만 결과가 그만큼 좋아졌다고 하기는 어려웠다. “왼손은 베이스, 오른손은 피아노”라는 일상적인 표현과 “Combination mode의 Timbre별 Key Window”라는 Korg X2의 전문 용어 사이에는 상당한 의미의 간격이 있다. 문서를 잘게 나누고 벡터를 만들고 순위를 다시 매긴다고 해서 그 간격이 저절로 사라지는 것은 아니었다.

그러다 문득 내가 왜 이 일을 하고 있는지를 다시 생각하게 되었다. 내가 필요한 것은 Korg X2에 관한 질문이라면 무엇이든 대답하는 인공지능이 아니다. 오래된 매뉴얼 두 권에서 내가 읽어야 할 페이지를 빨리 찾아주는 도구가 필요했을 뿐이다. 그렇게 생각하고 나니 오전에 만든 단순한 프로그램이 다시 달리 보였다.

질문을 입력하면 관련성이 높은 페이지 세 개 정도가 나온다. 그중 하나를 선택하여 원본 매뉴얼을 읽고, 설명이 앞뒤로 이어진다면 화살표를 눌러 한 페이지씩 넘겨 보면 된다. 결국 오후 늦게 프로그램에 추가한 가장 유용한 기능은 복잡한 RAG 기법이 아니라 PDF 페이지를 앞뒤로 넘기는 좌우 화살표였다. PDF를 작게 만드는 별도의 버튼도 처음에는 만들어 보았지만 그것조차 필요 없었다. 브라우저 창의 폭을 조절하면 PDF도 선명한 상태로 따라서 줄어든다. 몇 시간 동안 embedding, chunking, reranking을 돌아다닌 뒤 도착한 곳은 결국 책에서 관련 페이지를 찾아 앞뒤로 넘겨 읽는 방식이었다.

오늘 오후의 경험에서 얻은 교훈은 RAG나 embedding의 원리를 조금 더 알게 되었다는 것만은 아니다. 오히려 이미 잘 알려진 문제를 너무 처음부터 다시 풀려고 했다는 생각이 들었다. 문서 검색에는 오랫동안 사용되어 온 방법이 있고, embedding 검색과 reranking 역시 각각 어디에서 유용하고 어떤 한계를 갖는지 많은 사람이 이미 경험하였다. 그런데 AI가 코드를 척척 만들어 주니 “이것이 잘 안 되면 이것도 붙여 보자”는 식으로 하나씩 직접 시험하게 되었고, 어느 순간 남들이 이미 겪은 시행착오를 작은 Korg 매뉴얼 두 권을 가지고 다시 재현하고 있었다.

생각해 보면 AI를 이용한 프로그래밍에서 이것은 꽤 조심해야 할 점이다. 예전에는 새로운 방법을 시험하려면 코드를 작성하는 비용이 컸기 때문에 시작하기 전에 방법을 충분히 조사할 수밖에 없었다. 지금은 AI에게 부탁하면 몇 분 안에 다음 실험을 위한 코드가 나온다. 구현 비용이 낮아진 덕분에 오히려 충분히 조사하지 않고 여러 방법을 차례로 시험해 보는 일이 쉬워졌다. 코드를 빨리 만들 수 있다는 것과 문제를 빨리 해결한다는 것은 같은 뜻이 아니다.

다음에는 순서를 조금 바꾸어야겠다. 먼저 내가 풀려는 문제가 이미 어떤 이름으로 불리는지 알아보고, 그 문제에 널리 쓰이는 가장 단순한 방법이 무엇인지 찾아보는 것이 먼저다. 그것을 구현하여 실제로 써 본 뒤 부족한 점이 확인되었을 때에만 다음 단계를 추가하면 된다. AI 시대에는 코드를 만드는 비용이 크게 낮아졌다. 그래서 역설적으로 무엇을 더 만들 것인가보다 무엇을 만들지 않을 것인가를 판단하는 일이 더 중요해졌는지도 모르겠다.

609개의 chunk를 embedding하느라 노트북이 249초 동안 열심히 일한 것은 아마 그것을 배우기 위한 수업료였을 것이다. 다행히 API 사용료는 들지 않았다. 전기료는 조금 들었겠지만.