From where I left

Salvatore Sanfilippo

내가 떠났던 그 자리에서

원문은 Salvatore Sanfilippo님이 에 게재했습니다. 이 블로그 구독하기

나는 내 작업물에 강한 애착을 갖는 타입이 아니다. Redis를 떠나기로 결심한 뒤, 약 1620일 전(~4.44년) 나는 다시는 소스 코드나 커밋 메시지, Redis와 관련된 어떤 것도 들여다보지 않았다. 가끔 Redis가 필요할 때는 그냥 다운로드해서 컴파일만 했다. 그냥 “make”를 입력하면 됐고, 여러 해가 지난 뒤에도 Redis 빌드가 여전히 그토록 간단하다는 사실이 무척 반가웠다.

이런 거리 두기가 과거의 작업을 싫어해서 나온 건 아니었다. 장기적으로 보면 창의적인 작업의 비중은 점점 줄어들고, “프로젝트 관리” 성격의 일이 점점 더 큰 비중을 차지하게 되었다 — 많은 프로그래머들이 잘 해내는 전환이지만, 내게는 주특기가 아니었다 — 그럼에도 떠날 때까지도 나는 Redis 관련 작업을 여전히 즐기고 있었다. 하지만 나는 내 나이(지금 47세) 또래 대부분이 공유하는 시각, 즉 자신이 아직 젊다는 생각에는 동의하지 않는다. 나는 새로운 일을 하고 싶었고, 특히 글을 쓰고 싶었다. 가족과 더 많은 시간을 보내고 친지들을 돕고 싶었다. 확실히 휴식이 필요했다.

하지만 그 “글쓰기의 시간” 동안에도(참고로 지금도 글을 쓰고 있다), 나는 강도 높은 집필 사이사이에 휴식 삼아 종종 코딩으로 돌아갔다(글쓰기는 코딩보다 훨씬 더 고된 유일한 정신 활동이라고 느꼈다). 임베디드 프로젝트를 몇 개 했고, 신경망을 더 가지고 놀았으며, 텔레그램 봇도 만들었다. 이것저것 조금씩 건드렸다. 마구잡이로 해킹하는 건 재미있었지만, 길게 보면 진정한 목적이 없다는 느낌이 들었고, 나날이 기술 세계에 다시 합류해야 한다는 절박함이 커져 갔다. 동시에 나는 Redis 커뮤니티가 분열되는 모습을 보았고, 외부인의 입장에서도 꽤 우려스러운 일이었다.

그래서 결국 내가 Redis 생태계 안에서 다시 역할을 맡을 수 있을지도 모른다고 생각하기 시작했다. 어쩌면 회사의 커뮤니티에 대한 태도를 바꿀 수 있을지도 모른다. 어쩌면 Redis 코어를 다시 새로운 개발의 중심축으로 되돌리는 데 도움을 줄 수도 있을 것이다. 기본적으로 나는 일종의 “에반젤리스트”(이 직함이 썩 마음에 들진 않지만… 뭐, 뜻은 알 것이다)가 될 수 있을 것 같았다. 한편으로는 회사와 커뮤니티를 잇는 다리가 되고, 다른 한편으로는 프로그래밍 데모를 만들고 새로운 패턴을 고안해 설명하며, 새로운 것과 기존의 것에 대한 문서와 영상, 블로그 글을 쓰는 사람 말이다. 그리고 새로운 것의 설계는 어떨까? 현장에 있는 사람들의 작업과 그들이 겪는 어려움으로부터 배우고, 그것을 정제해 디자인 아이디어로 보고함으로써 Redis가 진화하도록 도울 수 있을 것이다.

뉴욕에서의 시간

어느 시점, 이제 12살이 된 딸아이가 생일을 맞아 뉴욕을 방문하고 싶어 했다. 딸은 내 삶에서 무엇보다 소중한 사람으로, 지성과 창의성, 사랑으로 내 일상을 밝혀 준다. 우리는 그래, 결국 좋은 생각이라며 결정했다. 최근 몇 년이 꽤 힘들었으니, 왜 안 되겠는가. 딸은 이제 어린아이보다는 소녀에 가깝다. 그래서 뉴욕에 있는 동안 나는 생각했다. 어쩌면 지금이 적절한 시기일지도 모른다, 파트타임 일을 할 수 있을 것 같았다. 얼마 전 화상 통화로 Redis의 새로운 CEO인 Rowan Trollope를 만났다. 그와 함께라면 회사가 커뮤니티와 맺는 관계의 미래, 그리고 코드베이스의 방향을 조율해 나갈 수 있을 것 같다는 느낌이 들었다. 그래서 그에게 메일을 썼다. 어떤 형태로든 다시 합류할 수 있을까? Rowan은 내 제안에 관심을 보였고, 우리는 빠르게 합의를 찾았다.

라이선스 변경에 대하여

사람들은 내가 *정말* 왜 이런 결정을 했는지, 위에 쓴 내용 외에 다른 뒷이야기가 있는 건 아닌지, 어떤 합의나 거액의 돈이 얽혀 있는 건 아닌지, 뭔가 수상하거나 불투명한 게 있는 건 아닌지 질문할 것이다. 하지만 때로 일은 매우 심심하다. 1. 내가 회사에 먼저 연락했다, 그 반대가 아니다. 2. 복귀한다고 해서 터무니없는 돈을 받는 것도 아니고, 어떤 상황을 이용하려는 것도 아니다 — 평범한 연봉이다(다만, 미리 밝혀두자면, 예전처럼 Redis 스톡옵션을 가지고 있다, 더도 덜도 아니다). 3. 나는 Redis의 라이선스 변경에 대해 큰 문제를 느끼지 않는다. 구체적으로 말하면, 커뮤니티와의 균열이 *정말로* 그것 때문이라고 생각하지 않는다. 하지만 사람들이 이 매우 중요한 문제에 대해 물을 것이니, 바로 지금 모든 진실을 말해 두는 편이 낫겠다.

라이선스 딜레마

나는 거의 평생 오픈소스 소프트웨어를 만들어 왔다. 하지만 나는 무신론자이면서도, 신앙이 삶의 고난을 견디는 데 도움이 된다면 다른 사람들이 신을 믿는 모습을 봐도 기쁘듯이, 오픈소스가 소프트웨어를 만드는 유일한 방법이라고 믿지는 않는다. 내가 Redis 개발을 시작했을 때는 내가 공동 창업자 두 명 중 한 명이었던 회사 안에서였고, 그곳에서 우리는 소프트웨어 코드를 비공개로 유지했다(Redis는 핵심 제품에 해당하지 않는다고 여겨져 공개되었다). 우리는 우리 서비스가 다른 사람들에 의해 복제되는 것을 원치 않았을 뿐이다, 그게 전부다. 그래서 이 문제에 관해서는 나는 극단주의자가 아니다 — 나는 소프트웨어 설계에 대해서만 극단적이다.

게다가 나는 개방성과 라이선스가 OSI가 말하는 그것만이라고 믿지 않는다. 라이선스는 할 수 있는 것과 할 수 없는 것들의 스펙트럼이라고 본다. 동시에 대형 클라우드 제공업체들이 시스템 소프트웨어 분야의 인센티브 구조를 바꿔 놓았다는 점에 대해 진심으로 우려하고 있다. 라이선스를 바꾼 프로젝트는 Redis만이 아니었고, 사실 Redis는 그 큰 무더기 중에서 마지막이었다. 그리고 최근 몇 년간 명확한 잠재적 비즈니스 모델이 없어 시작조차 되지 못한 프로젝트가 많았을 거라는 느낌이 든다. 그러니 Redis의 라이선스 변경은 내 결정이 아니었고, 어쩌면 내가 다른 라이선스를 선택했을지도 모른다. 잘 모르겠다, 수년간 현장을 떠나 있었고 비즈니스 압박도 없는 지금 시점에서 이를 다시 논하는 건 너무 쉽다. 하지만 전반적으로는 그 선택을 이해할 수 있다.

게다가 새로운 Redis 라이선스를 읽어 보면, 물론 BSD는 아니지만 기본적으로 Redis를 서비스로 판매하지 않는 한 이전과 매우 유사한 방식과 비슷한 자유도로 사용할 수 있다(내 말은, 여전히 Redis를 수정하고, 재배포하고, 영리 기업에서 상업적으로 무료로 사용하는 등 할 수 있다는 뜻이다). 심지어 원한다면 여전히 Redis를 서비스로 판매할 수도 있다, 다만 모든 오케스트레이션 시스템을 동일한 라이선스 아래 공개한다면 말이다(아마 아무도 그렇게 하진 않겠지만, 이는 이 라이선스의 카피레프트적 접근을 보여준다). 라이선스 문언은 SAAS 관련 부분을 제외하면 AGPL과 거의 같다. 그러니 OSI 승인을 받지 않았냐고? 그렇다, 하지만 나는 SSPL을 클로즈드 라이선스라고 부르는 데에는 동의하기 어렵다.

당신은 이렇게 말할 것이다(마치 들리는 듯하다): 진짜 문제는 OSS 프로젝트의 방향을 기업이 통제한다는 것이다! 그래서 결국 이해관계가 사용자층보다 기업 쪽으로 더 기울게 된다. 나는 기업의 직접적인 관여가 전혀 없는(외부 후원이 아니라면) 프로젝트가 많이 있다는 사실에 감사하지만, 글쎄, 이런 건 어떤가? 많은 대규모 프로젝트에서 기업의 관여는 오히려 올바른 경로에서 벗어나는 과정을 늦춘다. Redis의 경우에도 분명히 그랬다.

소프트웨어의 로빈 후드

과거로 잠시 돌아가 보자, Redis 초창기로.

Redis가 인기를 얻기 시작했을 때, 나는 계속해서 Redis 작업을 이어갈 방법을 찾고 싶었다. VMware가 내 작업을 후원하겠다고 제안하기 전이었다. 나는 비즈니스 모델에 대한 아이디어를 만지작거리기 시작했고, 뭔지 아는가? 그것은 어떤 형태로든 Redis 운영을 돕는 클로즈드 소스 제품 형태였다.(놀랍게도 이 아이디어와 관련된 저장소 중 하나가 지금도 온라인에 남아 있고, *15*년 전 커밋을 보여준다: https://github.com/antirez/redis-tools)

나는 일종의 오픈 코어 방식을 시도하려 했고, 유료 사용자에게 어떤 이점을 주기 위해 새로운 코드에 대해 BSD 라이선스 적용을 6개월 늦추는 것도 고민했던 기억이 난다. 지금도 내가 못된 사람이 되어 사용자를 상대로 이상한 장난을 쳤을 거라고는 생각하지 않지만, VMware 덕분에, 그리고 나중에는 더 본격적으로 Redis Labs 덕분에 될 수 있었던 존재가 되지는 못했을 것이다. 바로 오픈소스 소프트웨어의 진짜 로빈 후드, 회사로부터 충분한 보상을 받으면서도 회사의 이익을 위해서가 아니라 오직 Redis 커뮤니티의 최대 이익을 위해서만 일하는 사람 말이다. 이것은 직접 회사를 차리는 것보다 더 나은 구조라고 확신한다.

VMware, 그리고 나중의 Redis Labs는 나만을 후원한 게 아니었다. 저장소의 기여 내역을 잠깐 살펴보면, 역대 두 번째 기여자가 Oran Agra(Redis)이고 그다음이 Pieter Noordhuis(VMware)임을 알 수 있다, 그리고 그 뒤로도 이어진다.

그러니 기본적으로 나는 사용자층에만 집중하며 12년간 BSD 코드를 작성해 온 것이 좋은 거래였다고 생각하며, 이는 기뻐할 만한 일이다. 그리고 지금 내게 가장 중요한 점은 커뮤니티와의 균열이 라이선스 때문이 아니라는 것, 적어도 주로 라이선스 때문은 아니라는 것이다. 실제로 새로운 라이선스는 그 문제의 일부를 해결할 수 있다. 이제는 코어를 그냥 유지보수 모드로 두고 새로운 개발을 모듈에만 넣을 유인이 더 이상 없다. 새로운 라이선스 아래에서는 클라우드 제공업체가 수익 공유 없이 Redis 코드베이스를 그대로 베껴다 팔 수 없다(이게 정말 과한 요구였을까? 이것이 가능했다면 최근 보았던 모든 라이선스 변경 — Redis뿐만 아니라 — 을 막을 수 있었을 것이다). 새로운 라이선스와 함께라면 스포트라이트가 다시 Redis 코어로 돌아올 수 있고, 전 세계 개발자들의 손에 새롭고 흥미로운 기능들이 쥐어질 수 있다. 수십 명의 사람들이 정당한 보상을 받으며 GitHub 저장소에 유용하고 문서화가 잘 된 변경들을 푸시하는 모습 말이다. 이것 또한 내가 회사를 돕고 싶은 일 중 하나이며, 열심히 노력할 것이다. 우리는 라이선스 변경이 사용자층과 기능에 긍정적인 효과를 가져오도록 만들어야 한다. 그것이 내 생각이다.

AI, LLM 그리고 벡터 인덱싱에 대하여

하지만 이야기는 여기서 끝나지 않는다. Redis는 벡터 기능을 개발하는 데 관심을 갖기 시작했고, 더 일반적으로는 AI로 할 수 있는 종류의 프로그래밍을 지원하려 하고 있다. 요즘 나는 매일 Hacker News를 읽는데, AI와 새로운 발전을 싫어하는 수많은 기술인들을 본다. 또한 최신 모델을 깊이 있게 제대로 써보려는 노력조차 하지 않으면서(힌트: Claude AI는 독보적인 수준이다) 쓸모없다고 치부하는 사람들도 많이 본다. 나는 다르다. 나는 항상 신경망을 사랑해 왔다. 2003년에 첫 신경망 라이브러리를 만들었을 때 그 개념이 얼마나 강력하고 멋진지 완전히 충격을 받았다. 그리고 이제 2024년 말, 나는 마침내 이 분야에서 믿기 힘든 성과들을 보고 있다. 몇 년 전만 해도 공상과학처럼 보였던 일들이 이제 가능해졌다. Claude AI는 요즘 나의 추론/편집/코딩 파트너다. 덕분에 과거보다 훨씬 더 많은 일을 해낼 수 있게 되었다. AI 덕분에 오히려 *더 많은 일*을 하지만, 더 잘 해내게 된다. 최근 이탈리아 출판사를 위해 SF 단편을 썼는데, Claude가 일부를 비판해 준 덕분에 결말을 다시 써서 훨씬 더 나은 작품을 내놓을 수 있었다(Claude가 이야기의 한 줄이나 플롯을 쓰게 하지는 않았다. AI를 훌륭하게 쓰는 법은 기계에게 당신이 더 잘할 수 있는 일을 시키는 것이 아니다).

어제는 내 벡터를 8비트 양자화했을 때 내적 계산이 얼마나 더 빨라지는지 평가해야 했다. Claude에게 특정한 방식으로 설계된 벤치마크가 필요하다고 말하니, 2분 만에 테스트하고 수정해서 그것이 가치 있는 일인지 아닌지 파악할 수 있었다. 기본적으로 AI는 나를 대체하지 않았다. AI는 나를 가속했고, 내 작업에 대한 피드백으로 나를 더 나아지게 했다. 그리고 나는 (RAG의 인기와는 별개로 — RAG가 꼭 주된 응용도 아니고 가장 미래지향적이거나 유용한 것도 아니다. 모델의 컨텍스트는 점점 커지고 있고, 곧 인기 있는 모델들의 어텐션은 선형 복잡도를 갖게 될 것이다 — 라고 말하려다 잠시 샛길로 새었다) 내가 말하려던 것은 학습된 임베딩은 계속 남을 것이며, 벡터 검색은 여러 가지 이유로 Redis에 속한 것이라는 믿음이다. 첫째, 벡터 인덱스는 자료구조이며, 특히 느린 자료구조인데, 그런 자료구조는 메모리에서 아주 잘 동작할 수 있다. 또한, 나는 그것들을 노출할 완벽한 API를 찾았다고 생각하기 때문이다.

Redis를 설계하는 작업을 하는 동안 나는 항상 모순적인 성향을 보여 왔다. 프로젝트에 완벽하게 어울려 보이는 어떤 것들(이름이 붙은 Lua 스크립트, 해시 필드 만료 — 참고로 둘 다 지금은 Redis의 일부다)에 대해서는 언제나 “안 된다”고 말할 준비가 되어 있으면서도, 동시에 Lua 스크립팅 기능 — 당시에는 미친 짓처럼 보였지 않은가, Redis 안에 인터프리터라니?! —, 문맥상 어울리지 않아 보였던 Pub/Sub 기능, 그리고 스트림, 심지어 전산학 교과서에는 존재하지 않는 합성 자료구조인 sorted set 같은 것들까지 추가했다. 왜냐하면 나에게 Redis에 새로운 기능이 어울리는지는 두 가지에 달려 있었기 때문이다. 사용 사례와 내부 설계 적합성. 나에게 Redis는 “제품”이 아니라 프로그래머를 위한 레고였다.

벡터 셋

그래서 최근 나는 sorted set에서 영감을 받아 점수가 실제로 벡터인 새로운 자료형을 만들 수 있지 않을까 생각하기 시작했다. 그리고 Rowan과 대화를 나누는 동안 설계 문서를 쓰기 시작했고, 이어서 새로운 자료구조의 개념 증명을 구현하기 시작했다. 기존 라이브러리 중 하나를 쓰는 대신 HNSW를 처음부터 다시 구현했다(사소한 부분까지 모두 튜닝하고 싶었기 때문이다), Redis 방식으로 말이다. 그리고 글쎄, 이게 어떻게 끝날지는 아직 모르겠다, 아직 코딩 초기 단계이지만, 어쩌면 이 제안이 받아들여진다면 다시 코드 기여를 하게 될지도 모른다. 내가 구현한 모듈(나중에는 코어에 병합될 예정이지만 — 지금은 단순함을 위해 모듈 형태로 되어 있다)은 임베딩을 직접 다루는 새로운 명령어들을 구현한다. 힌트로 그것만 보여주겠다:

VSIM top_1000_movies_imdb ELE "The Matrix"  WITHSCORES
 1) "The Matrix"
 2) "0.9999999403953552"
 3) "Ex Machina"
 4) "0.8680362105369568"
 5) "Akira"
 6) "0.8635441958904266"
 7) "District 9"
 8) "0.8631418347358704"
 9) "The Martian"
10) "0.8608670234680176"
11) "The Bourne Ultimatum"
12) "0.8599717319011688"
13) "The Bourne Supremacy"
14) "0.8591427505016327"
15) "Blade Runner"
16) "0.8585404753684998"
17) "Metropolis"
18) "0.8572960793972015"
19) "Inception"
20) "0.8521313071250916"

VSIM, VADD, VCARD 등 당연히 있어야 할 것들이 있다. 정확히 sorted set의 아이디어지만, 다차원 점수(임베딩!)와 K-NN 매칭을 갖춘 형태다. 어떻게 생각하는가? 물론 그 위에는 효율성을 높이기 위한 많은 구현상의 트릭이 있다. 하지만 지금은 개념 증명 코드이니, 조금 더 작업해 보겠다. 스레딩, 차원 축소, 양자화 등 더 많은 것들을 구현하고 있다. 솔직히 꽤 재미있다.

보다시피 하이브리드 검색에 대한 언급은 없다. 벡터 스토어에 대한 최근 유행어 말이다. 다시 말하지만 이것이 Redis 방식이다. 개발자에게 역할을 주고 트레이드오프를 직접 결정하게 하는 것, 결국 무엇을 모델링하는지 가장 잘 아는 건 그들이기 때문이다. 키마다 하나의 벡터 인덱스를 갖게 되고, 프로그래머들이 sorted set으로 해냈던 것처럼 그들은 흥미로운 분할 전략, 새로운 스키마, Lua 스크립트, 패턴 등 자신들의 사용 사례를 모델링하는 데 필요한 모든 것을 발명해 낼 것이다.

물론 보통 연관된 아이템은 작은 문자열이나 문서 ID일 가능성이 높지만, 나중에 필터링할 수 있는 메타데이터를 포함해 더 복잡한 형태가 되는 것을 막을 것은 아무것도 없다(하지만 나는 그 유혹을 참으려 한다). 나는 많은 사용 사례가 사실 복잡한 서버 측 필터링을 필요로 하지 않으며, 데이터를 미리 파티셔닝함으로써 모델링할 수 있다는 느낌이 든다.

내가 큰 관심을 가지고 보는 것은 잠재적인 STORE 옵션을 추가하는 것이다. 결과를 사용자에게 반환하는 대신, 유사도를 점수로 하여 sorted set에 저장하는 옵션 말이다. 이 모든 것은 효율성, 확장성, 스크립팅 활용 가능성 등에 대해서도 복잡하고 흥미로운 영향을 미친다. 앞으로 몇 주, 몇 달 안에 이에 대해 더 이야기할 기회가 있기를 바란다.

좋아, 좋아, 이 블로그 글의 본론으로 돌아가자. 하지만 어쩌면 위의 내용이 *진짜* 핵심일지도 모른다, 흥미진진한 새로운 아이디어를 갖는다는 것 말이다.

그래서, 돌아왔다 🙂

이 모든 이야기를 한마디로 정리하면, 나는 돌아왔다. 그동안 Redis 커뮤니티가 해 온 모든 것에 대해 크게 감사를 전할 적절한 순간이라고 생각한다. 또 보자, 이 여정에 더 보탤 무언가가 있기를 바란다.

P.S. BlueSky에서 활동하고 있으니, 이 모든 진행 상황을 따라가고 싶다면 팔로우해 달라. https://bsky.app/profile/antirez.bsky.social

이 글은 muse-spark-1.2-contributor 모델을 사용해 번역했습니다.

댓글