The Sound of Stories의 첫 “게으른 완성본”을 들고 왔다. 서사 구조는 지키면서도 사용자 입력에는 유연하게 반응하는 인터랙티브 이야기를, 일단 생성해 내는 데까지는 성공했다.
The Sound of Stories 작업 중 데모
이 흐름을 처음부터 끝까지 한 번 완주시키는 일은, 첫 공개 발표 이후로 계속 마음에 걸려 있었다. 최초 생성을 돌리는 건 쉬웠다. 정작 걸렸던 건 이거였다. 사용자의 입력을 기억하는 데서 끝내지 않고, 시작과 끝이 분명한 구조화된 서사의 제약 안에 그 입력을 어떻게 논리적으로 편입할 것인가? 이 문제를 ‘이산적이면서 무한한 분포’ 같은 식으로 볼 수도 있겠다. 내 덕후 머리에는 꽤 신나는 표현이지만, 그래서 정확히 어디서부터 풀어야 하는지에는 전혀 도움이 되지 않는다.
결국 도움이 된 건 다른 사람과 문제를 말로 풀어 보면서 생각을 정리한 일이었다. 특히 이 문제가 D&D식 진행에서 생기는 문제와 비슷하다는 이야기를 하고 있었는데, Jia Qi가 체크포인트를 떠올리게 해 줬다. Baldur’s Gate 같은 게임은 특정 목표를 달성하는 방식에 꽤 다양한 선택지를 준다. 맞다. 그래도 결국은 정해진 체크포인트에 도달해야 한다. 그래서 서사의 구조를 붙들고 앉아, 이것을 체크포인트 단위로 어떻게 쪼갤 수 있을지 생각하기 시작했고, 아래와 같은 .json로 바꿨다.
{
"title": "The Boy Who Wanted a Drum – by Kamini Ramachandran",
"story_details": {
"protagonist_gender": "male",
"protagonist_name": "the boy",
"story_setting": "a small hut"
},
"checkpoints": [
{
"id": "intro",
"text": "Once upon a time, there lived a poor woman and her little son. They lived in a small hut together. The little boy wanted a drum. A drum he could tap, beat, and play. Ta Di Gin A Thom! I want a drum! The boy kept asking his mother for a drum, all day and all night long. And so it was, that the next morning, the woman went to the market to sell the cloth that she had woven.",
"choice": "drum"
},
{
"id": "encounter_0",
"text": "And when she had sold all the cloth, she realised that the coins were not enough to buy her son a drum. As she walked on her way back home, she saw a stick. She picked up the stick and took it home. Ta Di Gin A Thom! I want a drum! Son, take this stick and pretend that it is a drum. The boy took the stick, and he tapped it on the ground (sound effects) He tapped it on the water pot (sound effects) He tapped it on the door (sound effect) He was delighted by the sound it made!",
"choice": "continue"
},
{
"id": "encounter_1",
"text": "Ta Di Gin A Thom! I have a stick! On the way he met an old woman looking very sad. She sat beside a small wood stove trying to fan the flames. Grandmother, grandmother, why do you look so sad? I have no wood to make the fire to cook the chapatti. The boy remembered his stick! He gave it to the old woman who used the stick to start the fire to cook some chapati. Thank you boy! Here, take some chapatis with you, I have no need for so many.",
"gift": "chapati"
},
...또 하나 정말 도움이 된 건 내가 적어 둔 메모를 그대로 따른 것이었다. 복잡하게 만들지 말 것. 일단 가능한 한 가장 단순한 해법으로 깎아 들어가자. 복잡한 건 나중에 얼마든지 얹으면 된다… 그래서 에이전트에 미쳐 날뛰는 대신(director, scriptwriter, assistant 역할을 맡은 계층형 에이전트 팀을 만들면 어떨까!?), LLM 체인 2개, 단순한 대화 메모리, 간단한 if 검사만으로 아주 멍청한 이야기의 “게으른 완성본”을 내놓을 수 있었다.
if next_segment_id < len(story_data["checkpoints"]):
# then you continue the story and use memory to-date as well as the next segment as context이 단계에서 개발을 과하게 복잡하게 만들지 말라는 내 조언을 내가 들었다는 점에 대해 스스로 등을 두드려 준다.
그 밖에도, 작업하면서 배운 흥미로운 것들이 몇 가지 있다.
-
의존성 관리: 이제야
pyenv,virtualenv,poetry가 어떻게 맞물려 특정 디렉터리 전용 개발 환경을 띄우는지 감이 온 것 같다. 그러니까pyenv는 Python 버전 관리용,virtualenv는 격리된 환경을 만드는 용도,poetry는 패키지 의존성과 나중의 배포를 관리하는 용도다. -
프롬프트 “엔지니어링”: 시간의 80%는 그냥 쓸 만한 최적의 프롬프트를 찾는 데 들어간다. LLM 기반 개발은 무엇이든, 다른 일을 시작하기 전에 처음부터 가장 잘 먹히는 프롬프트를 반복해서 다듬는 것만으로도 엄청난 이득을 볼 거라고 생각한다. 나는 이 작업이 아주 지루하다. 그리고 이 부분은 앞으로 개발 과정에서 언어학 전공자들과 협업해, 정말로 외주를 맡기고 싶은 잠재적 전문 경로처럼 보인다.
-
결정론적 시스템과 확률적 시스템: 이런 시스템에도 조정할 수 있는 흔한 하이퍼파라미터들이 있기는 하다. 하지만 사람들이 결과를 절대적 확실성으로만 보여 주고 싶다고 말하는 걸 들으면 나는 늘 조금 속이 불편해진다. 사실 우리가 지금 이 순간 존재한다는 현실 말고, 인생에 100% 절대 확실한 것은 없다. 나머지는 대체로 그렇게 되리라는 기대가 있고, 실제로도 보통 그렇게 되지만, 확률이 1인 일은 삶에서 아주 드물다는 사실은 그대로 남는다. 내가 해야 했던 반복 작업의 상당수는 결국
temperature파라미터 주변을 맴돌았다. 그리고 어느 순간에는 그냥 두 손을 들고, 같은 입력을 넣어도 이야기가 100% 똑같이 재현될 수는 없다는 걸 받아들여야 했다. 이 지점에서 인간 조직의 관리자와 QA/QC의 역할을 떠올리게 된다. 우리는 인간의 입력과 출력이 만들어 내는 변동성을 어떻게 관리하려고 애쓰는가. 어쩌면 신뢰할 만한 A.I. 시스템을 만들기 위해 거기서 가져올 수 있는 무언가가 있지 않을까? -
A.I. 다양성의 필요성: 처음에는 Kamini의 목소리로 생성한 짧은 표준중국어 음성 조각이 꽤 기분 좋게 놀라웠다. 휴대폰으로 녹음한 약 1분짜리 영어 음성을 바탕으로 즉석 음성 클론을 만들고, 거기서 표준중국어를 추론해 낸 것이었다. 하지만 생성되는 시퀀스가 길어질수록 품질이 급격히 무너진다는 점은 금방 분명해졌다. 표준중국어 음성 출력에서 성조가 더 자주 틀리고, 말하는 속도가 이상해지고, 단어를 제대로 끊지 못하는 식이었다. 텍스트 생성도 마찬가지다. GPT-4는 대부분의 경우 이야기를 영어에서 표준중국어로 순진하게 직역하듯 생성하고 있다는 게 눈에 보였다. 말할 것도 없이, 이 경험은 왜 더 다양하고 더 특화된 LLM 모델이 필요한지 몸으로 이해하게 해 줬다. 동시에 인터넷에서 영어라는 언어가 앞으로 어떤 추가적인 지배력을 갖게 될지도 생각하게 됐다. 가장 두드러진 모델들이 전부 영어 중심으로 조율되어 있으니, 영어 콘텐츠를 쏟아내는 일이 훨씬 쉽기 때문이다. 내 모어가 이 때문에 앞으로 더 줄어든다면 조금 슬플 것 같다. 언어를 잃는다는 건 세상을 바라보는 또 하나의 방식, 또 하나의 창을 잃는 것과 비슷하지 않나? 그런데 또 중국어 LLM을 훈련하는 데 쓸 수 있는 입력 데이터의 품질을 생각하기 시작하면, 허허. 요점은 이렇다. 훈련에 쓸 수 있는 데이터셋을 더 많이 만들기 위해 어떤 투자를 하고 있는지 이야기하지 않고는, 디지털 포용이나 A.I.의 다양성을 말할 수 없다. 그렇다, 편향은 문제다. 하지만 문화적으로 더 다양하고 대표성 있는 훈련 데이터셋을 디지털화하기 위해 실제로 무엇을 하고 있는가? 그러면 사람들은 입력 데이터 훈련에 대한 정당한 보상, 옵트아웃 같은 이야기를 꺼내기 시작한다. 이런 논의는 A.I. 훈련의 작동 방식과 과정을 조금만 더 잘 이해해도 꽤 도움이 된다. 그래야 어떤 생각들이 얼마나 비현실적이거나 잘못 알고 나온 것인지 아주 빨리 보이니까. 뭐 아무튼, 이건 또 다음에 할 이야기인 것 같다.
다시 The Sound of Stories로 돌아오면, 끝없이 이어지는 이야기라는 무한 게임과, 여기서 내가 한 것처럼 시작과 끝이 분명한 구조 사이에는 뭔가 흥미롭게 말할 수 있는 지점이 있다고 생각한다. 일종의 예술적 선언이니 의도니 어쩌고저쩌고. 삶 자체와 견주어 끌어낼 수 있는 교훈이나 평행선도 있겠지. 하지만 그 이야기는 잠시 뒤로 미뤄 두려고 한다. 이제는 이 경험 안에 직접 넣고 싶은 신경 오디오 합성용 VAE 모델을 훈련하는 쪽으로 관심을 돌릴 차례다. 계속 지켜봐 주시길! ;)
원래 PubPub의 erniesg.pubpub.org/pub/g6zjtf2s에 게시되었다.