Logo Ernie.SG

개발자 일기: 이야기의 소리

2024년 2월 13일
6분 읽기
사용 가능한 태그가 없습니다

The Sound of Stories의 첫 번째 “게으른 완성”을 가져왔다. 서사 구조를 지키면서도 사용자 입력에 유연하게 반응하는 인터랙티브 스토리를 생성하는 데 성공했다.

The Sound of Stories WIP Demo

이 한 바퀴를 완성하는 일은 우리가 처음 대중에게 발표한 이후 계속 마음에 걸렸다. 초기 생성을 시작하는 것은 쉬웠지만, 나를 괴롭힌 질문은 이것이었다. 사용자의 입력을 기억할 뿐 아니라, 명확한 시작과 끝을 가진 구조화된 narration의 제약 안에서 그것을 어떻게 논리적으로 통합할 수 있을까? 이 문제를 이산적이고 무한한 분포로 framing할 수도 있겠고, 내 geek한 머리에는 꽤 흥미롭게 들리지만, 정확히 어떻게 풀기 시작해야 하는지에는 전혀 도움이 되지 않았다.

결국 도움이 된 것은 다른 사람과 이 문제를 말로 풀어보며 생각을 정리하는 일이었다. 특히 우리는 내 문제가 D&D 문제와 비슷하다는 이야기를 했고, Jia Qi가 checkpoints를 떠올리게 해 줬다. Baldur’s Gate 같은 게임은 특정 목표를 달성하기 위해 여러 선택지를 제공하지만, 그래도 명확한 checkpoint에는 도달해야 한다. 그래서 나는 서사 구조를 들여다보며 그것을 checkpoints로 분해할 방법을 생각했고, 아래와 같은 .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"
    },
    ...

또 하나 아주 유용했던 것은 내 머릿속 메모를 지키는 일이었다. 이걸 과하게 복잡하게 만들지 말자. 우선 가능한 가장 단순한 해법으로 hack해 보고, 어려움은 나중에 얼마든지 층층이 올릴 수 있다… 그래서 에이전트에 미친 듯이 뛰어들지 않았다. (director, scriptwriter, assistant 역할을 가진 계층형 에이전트 팀을 만들면 어떨까!?) 대신 2개의 LLM chain, 단순한 conversational memory, 그리고 간단한 if check로 아주 멍청한 “게으른 완성”을 전달할 수 있었다.

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

이 단계에서 개발을 과하게 복잡하게 만들지 말라는 내 조언을 스스로 따른 것에 대해 셀프 칭찬.

그 외에도, 진행하면서 배운 흥미로운 것들이 있다.

  • Dependency 관리: 이제야 pyenv, virtualenv, poetry가 디렉터리별 개발 환경을 띄우기 위해 어떻게 맞물리는지 이해한 것 같다. pyenv는 Python 버전 관리용, virtualenv는 격리된 환경 생성용, poetry는 패키지 의존성과 최종 배포 관리용이다.

  • Prompt “engineering”: 내 시간의 80%는 최적의 프롬프트를 찾는 데 쓰인다. LLM 기반 개발은 무엇이든, 다른 작업을 시작하기 전에 처음부터 쓸 만한 최고의 프롬프트를 반복 개선하는 데서 엄청난 이득을 볼 것이라고 생각한다. 나는 이 작업이 아주 지루하고, 언어학 전공자들에게 잠재적인 전문 경로가 될 수 있다고 본다. 앞으로 이 개발의 일부를 실제로 외주화하기 위해 그들과 협업하고 싶다.

  • 결정론적 시스템 vs. 확률적 시스템: 이런 시스템에는 조정할 수 있는 일반적인 하이퍼파라미터가 있지만, 사람들이 절대적인 확실성으로만 결과를 보여 주고 싶다고 말할 때마다 나는 늘 조금 불편하다. 사실 지금 이 순간 우리가 존재한다는 현실을 제외하면, 인생에는 절대 100% 확실한 것이 없다. 그 밖의 모든 것에 대해서 우리는 기대를 가질 뿐이고, 대체로 그렇게 되곤 하지만, 확률이 1인 일은 삶에 거의 없다. 내가 해야 했던 많은 반복 작업은 단순히 temperature 파라미터를 중심으로 이루어졌고, 어느 순간에는 손을 들고 같은 입력으로도 이야기를 100% 안정적으로 재현할 수 없다는 것을 받아들여야 했다. 이것은 인간 조직에서 관리자와 QA/QC의 역할, 그리고 인간 입력과 출력의 분산을 관리하려는 방식에 대해 생각하게 한다. 신뢰할 수 있는 A.I. 시스템을 만드는 데 옮겨 올 수 있는 무언가가 거기에 있을지도 모른다.

  • A.I. 다양성의 필요성: 처음에는 Kamini의 생성된 중국어 음성 짧은 조각에 꽤 기분 좋게 놀랐다. 영어로 된 약 1분짜리 휴대폰 음성 녹음을 바탕으로 한 즉석 음성 클론에서 추론한 것이다. 하지만 생성 시퀀스가 길어질수록 품질이 크게 떨어진다는 것이 금방 분명해졌다. 중국어 음성 출력은 성조를 더 많이 틀리고, 이상한 속도로 말하며, 단어를 제대로 끊지 못했다. 텍스트 생성도 마찬가지였다. GPT-4가 대체로 이야기를 순진하고 직접적인 영어-중국어 텍스트 생성으로 처리하고 있다는 것이 분명했다. 말할 필요도 없이, 이 경험은 왜 더 다양하고 더 구체적인 LLM 모델이 필요한지 이해하게 해 주었다. 또한 가장 두드러진 모델들이 모두 영어 중심으로 튜닝되어 있어 영어 콘텐츠를 대량 생산하기가 훨씬 쉽다는 점을 생각하면, 영어라는 언어가 인터넷에서 어떤 추가적인 지배력을 갖게 될지도 생각하기 시작했다. 내 모어가 앞으로 이 때문에 더 약해진다면 조금 슬플 것 같다. 언어를 잃는다는 것은 세상을 바라보는 또 하나의 방식, 또 하나의 창을 잃는 것과 같기 때문이다. 그런데 중국어 LLM 모델을 학습하는 데 사용할 수 있는 입력 데이터의 품질을 생각하기 시작하면, 허허. 요점은 이것이다. 훈련에 사용할 수 있도록 더 많은 데이터셋을 제공하기 위해 어떤 투자를 하고 있는지 이야기하지 않고는 디지털 포용과 A.I. 다양성을 말할 수 없다. 물론 편향은 문제다. 하지만 더 문화적으로 다양하고 대표성 있는 데이터셋을 훈련용으로 디지털화하기 위해 무엇이 이루어지고 있는가? 그러고 나면 사람들은 입력 데이터 훈련에 대한 공정한 보상, opt-out 등을 이야기하기 시작한다. 이 모든 논의는 A.I. 훈련의 메커니즘과 프로세스를 더 잘 이해하는 데서 이득을 볼 수 있다. 그래야 어떤 생각들이 얼마나 비현실적이거나 잘못 이해된 것인지 금방 알 수 있기 때문이다. 어쨌든 그건 아마 다음에 다룰 주제일 것이다.

The Sound of Stories로 돌아오면, 결코 끝나지 않는 이야기라는 무한 게임과 내가 여기서 만든 명확한 시작과 끝이 있는 이야기 사이에는 어떤 예술적 진술이나 의도 같은 흥미로운 이야기를 할 수 있을 것 같다. 삶 자체와 견주어 볼 교훈이나 평행선도 있을 것이다. 하지만 당분간은 이 생각을 한쪽에 두고, 경험에 직접 통합하고 싶은 신경 오디오 합성용 VAE 모델 훈련으로 관심을 돌리려 한다. 기대해 달라! ;)


원래 PubPub에 erniesg.pubpub.org/pub/g6zjtf2s로 게시되었습니다.