들어가며
'디깅 뮤직(Digging Music)'은 음악에 대한 번역과 해설, 그리고 비평을 함께 담아내는 위키 기반의 프로젝트입니다. 이 위키를 채워나가는 작업은 단순히 가사를 번역하는 것을 넘어, 문화적 맥락을 해석하고 주석을 다는 복잡한 과정입니다. 저는 이 작업을 자동화하기 위해, 세 번의 버전을 거쳐 점진적으로 시스템을 고도화해 왔습니다.
이 글은 그 과정에서 배운 점과, LLM을 활용한 자동화 설계의 통찰을 기록한 개발 회고입니다.
2025.06.19 - [프로젝트/디깅 - 종합음악플랫폼] - [디깅 뮤직 23편] 디깅 뮤직을 오픈까지 하면서 느낀점
[디깅 뮤직 23편] 디깅 뮤직을 오픈까지 하면서 느낀점
1년 6개월동안 만든 디깅 뮤직https://diggingmusic.kr 너무 많은 시간을 들인 것 같지만,, 배운 게 많다. 1) 처음엔 2달이면 끝날 줄 알았다.처음엔 정말 2달이면 끝날 줄 알았다. 기획만 잘 세우면, 머릿
thingdong.tistory.com
버전별 발전 과정
🔹 버전 1: 단순 번역 자동화
디깅 뮤직 초기에는 가사 DB 구조가 비효율적인 상태였다. 당시에는 가사 한 줄마다 별도의 엔티티가 필요했기 때문에, 한 곡을 저장하려면 수십 개의 엔티티를 생성해야 했고, 그만큼 시간과 리소스도 많이 들었다. 서버 비용도 자연스럽게 증가했다.
자동화된 번역 기능은 단순히 이미 존재하는 영어 가사를 받아 한 줄씩 번역 결과를 출력하는 수준이었고, 그 출력 역시 사람이 보기에는 다듬기 어려운 형태였다. 필요한 출력 포맷이 복잡해서 LLM이 그 구조를 안정적으로 따르게 만드는 것도 쉽지 않았다.
🔹 버전 2: 리팩토링 후의 구조화 + 번역
DB 구조가 정비된 이후, 자동화는 본격적으로 가속화되었다. Genius에서 가사와 주석을 크롤링하고, 이를 구조화된 형태로 저장한 뒤, 번역과 설명, 소개글, 여담 생성까지 자동으로 처리하는 흐름을 구축했다.
이전 버전에서는 각 줄마다 별도 엔티티를 만들어야 했던 반면, 이제는 정돈된 DB 덕분에 적은 리소스로 더 많은 데이터를 처리할 수 있게 되었다. 컴퓨팅 리소스와 서버 비용도 크게 줄었다.
그러나 이 시기의 자동화는 여전히 완전한 통합 흐름이라고 보긴 어려웠다. 번역, 설명, 소개, 여담은 각기 다른 모델 입력과 프롬프트에 의해 서로 완전히 독립적으로 생성되었다. 번역은 번역만을 위한 입력, 소개는 소개에 필요한 배경 정보만 넣어 수행되는 구조였다.
이로 인해 문제가 발생했다. 예를 들어, 한 곡의 주제가 은유와 반어로 구성되어 있을 때, 번역은 이를 직역해버리고, 소개는 정반대 해석을 하며, 해설은 완전히 다른 테마를 중심으로 전개되는 일이 잦았다. 모든 출력이 따로 노는 현상이었다. 심지어 어떤 곡은 설명에선 슬픈 노래라고 하고, 소개는 감미로운 사랑 노래라고 표현하는 등 의미적 충돌까지 발생했다. 상징과 비유를 사용하거나, 반어법을 사용하면 내용이 아예 반대가 되기도 했다.
이러한 분산 처리 구조는 '정확한 해설'이라는 목표에는 치명적이었다. 컨텍스트 공유 없이 생성된 결과물들은 연결성도 떨어졌고, 사람이 일일이 다시 읽고 수동으로 통합해주어야 했다.
결국 이 시점의 자동화는 '작업 효율 향상'은 이루었지만, '품질 일관성 확보'라는 과제는 남겨놓은 상태였다.
🔹 버전 2.5: 문맥 공유
버전 2의 문제를 해결하기 위한 중간 단계로, 자동화 흐름에 additional_info라는 입력 항목을 도입했다. 이는 사람이 곡의 주제나 핵심 키워드를 사전에 파악한 뒤, LLM에게 해당 정보를 힌트로 제공하는 방식이다.
이렇게 하니 번역, 해설, 소개, 여담 간의 주제가 일치하기 시작했고, 이전처럼 각 파트가 제각각 다른 방향을 가리키는 현상은 줄어들었다. LLM이 곡의 중심 주제를 인지한 상태에서 해석을 하게 되었기 때문이다.
그러나 여전히 완전한 해결은 아니었다. 각 생성 항목의 순서는 여전히 비일관적이었고, 내가 수동으로 additional_info를 작성하는 데 많은 시간과 노력이 들었다. 결국 이 단계의 자동화는 "사람이 미리 방향을 제시하면 LLM이 어느 정도 따라간다"는 수준이었다. 사람이 곡에 대한 충분한 배경 지식을 갖고 있어야만 통일된 출력이 나올 수 있었다.
🔹 버전 3: 문맥 기반 해설 + 포맷 + 컨트롤 가능한 입력
이 버전부터 진짜 자동화의 가능성을 보기 시작했다. 버전 2.5까지의 흐름을 반복하면서 문서를 수동으로 완성하는 과정을 계속하다 보니, 사람의 작업에도 자연스러운 절차가 생기기 시작했다.
예를 들어:
1) 크롤링한 데이터 + 가사로 소개 작성 (이때 일부 중요 가사에 대한 의미 설명도 포함)
2) 이 소개를 바탕으로 전체 번역 생성
3) 같은 소개를 바탕으로 해설 작성
4) 소개와 외부 데이터를 조합해 여담 생성
이 흐름이 정착되자, 자동화로 옮기는 건 상대적으로 단순했다. 처음엔 엉켜 있던 비선형 루틴을 하나씩 풀어내어, 순차적인 함수형 파이프라인으로 바꿔버렸다.
즉, 본래 사람의 작업에서 "왔다갔다 하며 고치던 흐름"을 generate_intro → generate_translation → generate_annotation → generate_behind 형태로 재구성했고, 각 단계를 함수로 분리하면서 전체 흐름을 자동화할 수 있었다.
이 구조 위에 약간의 프롬프트 엔지니어링과 파인튜닝을 적용하자, 문체도 위키에 맞춰 안정적으로 나오게 되었고, BBCode 문법도 자동으로 포함되었다.
결과적으로 이 버전은 처음으로 "단순 반복 처리"가 아니라, 선형으로 사고하는 구조를 모사하는 자동화 흐름이었다.
🔹 버전 4 (예정): 비가시적 정보의 생성
앞으로 구현할 버전은, 외부 데이터에 존재하지 않는 정보까지 LLM이 생성할 수 있도록 할 계획이다. 단순히 크롤링 데이터를 요약하거나 정보를 재조합하는 것이 아니라, 검색해도 나오지 않는 설명, 즉 LLM만이 만들어낼 수 있는 해설과 통찰을 위키에 담는 것이 목표다.
예를 들어, 특정 가사에 대한 문화적 연관성, 시대적 해석, 숨겨진 아이러니, 또는 해석이 분분한 라인에 대해 복수의 시각을 제시하는 등, 기존 데이터를 초월한 설명을 생성하려 한다.
이를 위해선 '단순 문맥 공유' 이상의 문장 단위 유사도 분석과 개체명 기반의 정렬이 필요하다. 따라서 string matching 알고리즘이 핵심 기술 요소로 들어갈 예정이며, 주석과 가사를 보다 정밀하게 매칭시키기 위한 알고리즘적 접근이 요구된다. (이 부분에 대한 기술적 설명은 추후 정리할 계획이다.)
다만, 버전 3의 전체 흐름을 더욱 안정화하고, 출력의 품질과 일관성을 높이는 일이 우선이다.
Supervised Fine-tuning vs DPO, 그리고 내가 선택한 것
Supervised Fine-tuning은 "user" → "assistant" 형태의 대화 데이터로 모델을 학습시키는 방식이다.
DPO는 좋은 응답과 나쁜 응답을 비교해 ‘더 나은 답변’을 선호하게 만드는 학습 방식이다.
초기에는 번역 품질을 올리고자 Supervised Fine-tuning을 사용해 파인튜닝을 했다.
Supervised Fine-tuning은 일반적으로 "user" → "assistant" 형태의 대화 데이터를 학습시켜 모델이 특정 문체나 출력을 따르도록 만드는 방식이다. 문장 형식을 맞추거나, 말투를 일관되게 유지하는 데는 꽤 효과적이다.
그러나 해설과 번역을 다루는 내 작업에는 한계가 있었다. 일단 품질 향상이 기대만큼 크지 않았다. 그리고 가장 큰 문제는 좋은 데이터(정답)만 모으기 어렵다는 점이었다.
내 서버 구조에서는 사람이 LLM이 만든 결과물을 수정했을 때, 그 수정된 부분만 '오답의 교정'이라고 간주할 수 있다. 즉, LLM이 낸 80%의 결과물은 멀쩡하고 20%만 고친다고 하면, 실제로는 그 20%만 학습에 활용하면 된다. 하지만 Supervised 방식은 모든 데이터에 대해 비율을 맞춰서 입력-출력을 짝지어야 한다.
이건 오히려 번거로웠다. 내가 가진 데이터는 '아직 사람이 검수하지 않은 데이터', '정답처럼 보여서 넘어간 응답', 그리고 '명확히 틀려서 고친 응답'이 뒤섞여 있는데, 검수를 하고 넘어간 내용과 검수가 안된 내용을 구분할 방법이 없었다. 내가 서버에 그런 태깅 구조를 만들어두지도 않았기 때문이다.
또한 LLM의 오답에는 공통된 패턴이 없었다. 만약 내가 포맷이나 말투를 통일시키는 게 목표였다면 Supervised 방식으로 충분했겠지만, 내 작업은 "둘 다 틀리지는 않지만, 하나가 더 나은 경우"를 고르는 일이었다.
즉, 이건 정답/오답의 문제보다는 선호도의 문제였다. 그래서 Supervised Fine-tuning 대신, DPO(Directional Preference Optimization)를 선택했다.
DPO는 사람이 고른 '더 나은 응답'을 선호하게끔 모델을 조정한다. 같은 입력에 대해 '이쪽이 더 나아'라는 방향성을 알려주는 방식이기 때문에, 내 작업처럼 "둘 다 말은 되지만 하나가 더 자연스럽다"는 경우에 최적화된 방식이었다.
자동화 설계를 하면서 배운 점
1. 자동화는 '마지막' 단계에서 해야 한다
자동화는 개발 과정에서 제일 먼저 손댈 부분이 아니라, 오히려 가장 마지막 단계에 설계되어야 한다. 왜냐하면 자동화는 이미 확립된 흐름을 반복시키는 일이지, 불안정한 흐름을 정리해주는 기능이 아니기 때문이다.
결국 자동화는 '편해지기 위해' 도입하는 게 아니다. 그보다는, 사람이 반복해서 같은 작업을 수행해보고, 그 흐름이 충분히 쌓였을 때 비로소 효율화 도구로서 적용할 수 있는 수단이다.
초기에 완벽한 모습을 상상하면서 자동화를 기획하면, 오히려 문제 해결이 너무 어려워진다. 마치 실이 엉켜 있는 상태에서 한 번에 다 풀려고 하는 것처럼 느껴진다. 이럴 땐 한 가닥씩, 할 수 있는 부분부터 조심스럽게 푸는 게 맞다.
내 경험상, 자동화는 "사람이 하는 일"을 해체하고, 조금씩 LLM이나 시스템에 위임하는 구조를 만드는 과정이다. 그 과정에서 일부는 여전히 사람이 해야 한다. 예를 들어 번역의 어색한 부분은 사람이 수정해야 하고, 주석이 잘못 붙은 경우엔 사람이 골라내야 한다. 하지만 그 비율은 줄여갈 수 있다.
자동화란 결국 '검수 시간을 조금씩 줄여가는 흐름'이다. 완전한 자동화란 검수가 필요 없는 정도까지 품질이 올라가는 과정을 의미한다. 따라서 자동화는 개발 사이클의 맨 마지막에, 이미 사람이 여러 번 해보고 정립한 절차 위에서만 빛을 발할 수 있다.
2. 직접 작업하면서 선형 구조를 설계해야 한다
많은 작업은 본질적으로 비선형적이다. 사람이 하는 일은 앞뒤를 왔다 갔다 하며 판단을 바꾸고, 중간 결과를 다시 되돌리며 조정하는 흐름으로 이루어지는 경우가 많다. 그러나 자동화는 이런 흐름을 그대로 모사할 수 없다. 그 이유는 간단하다. AI는 맥락 판단을 스스로 하지 못하고, 사람처럼 중간에 “이건 잘못됐네” 하고 거슬러 올라갈 수 없기 때문이다.
따라서, 자동화를 위해서는 사람이 먼저 그 복잡한 흐름을 선형적인 절차로 재구성해놓아야 한다. 즉, 수동으로 작업할 때 가장 효율 좋은 방법도 선형 흐름을 갖는 형태일 수밖에 없다.
예를 들어 디깅 뮤직에 한 트랙을 해설한다고 하자. 곡 소개 → 여담 → 가사 번역 → 가사 설명의 순서로 작업하려고 해도, 작업을 하다 보면 다음과 같은 일이 발생한다:
- 번역을 하고 나서 해설을 붙이다 보니, “내가 해석을 잘못했나?” 싶어 다시 번역을 고쳐야 할 때가 있다.
- 해설을 모두 마친 뒤, “이 곡은 생각보다 정치적 맥락이 크네”라는 통찰이 생기면, 처음 썼던 소개글이 주제와 어긋나 보여 다시 쓰게 된다.
이처럼 현실의 작업 흐름은 복잡하고, 왔다 갔다 하는 경향이 있다. 마치 집을 짓는 것과 비슷하다. 구조 설계를 마치고 마감재를 고르고 있었는데, 그 마감재 덕에 구조를 바꾸는 게 더 낫다는 걸 깨닫게 되는 것처럼 말이다. 이런 비선형적 사고 과정은 인간에게 자연스럽지만, LLM이나 시스템은 이를 추적하거나 반영하기 어렵다.
결국 이 흐름 속에서 우리가 해야 할 일은 다음과 같다:
- 반복적인 작업을 통해 감을 잡는 것 — 여러 번 작업을 하면서, 어떤 순서가 가장 효율적인지를 체감해야 한다.
- 그 감각을 구조화하는 것 — 선형적인 절차를 만들기 위해, 단계마다 어떤 입력이 필요한지, 어떤 출력을 만들어야 다음 단계로 이어질 수 있는지를 명확히 해야 한다.
예를 들어, ‘곡 소개 → 번역 → 해설 → 여담’이라는 흐름이 반복될수록, 어떤 정보가 먼저 확보되어야 뒤가 수월한지 알 수 있다. 그리고 그 흐름을 코드로 옮기기 쉬워진다.
요약하자면, 자동화를 위해 필요한 선형 구조는 하늘에서 뚝 떨어지는 게 아니다. 사람이 비선형적인 작업을 여러 번 반복하면서 경험적으로 만들어낸 자연스러운 루틴이어야 한다. 이 루틴을 바탕으로 자동화의 흐름을 설계할 수 있다.
3. LLM은 줄 번호를 못 센다
GPT는 본질적으로 줄 번호 개념이 없기 때문에, “이 설명이 가사의 몇 번째 줄에 해당하는가?” 같은 매핑을 안정적으로 하지 못한다. 그래서 줄 인덱스를 수동으로 잡아줘야 한다.
그래서 가사 번호를 앞에 달아줘서 해결했다.
[가사]
[1]여전히 밤이 되면 외로워
[2]넓어지고 많아진 거 빼곤 다 그대로
[3]매일 쏟아지는 새로운
4. 자동화 자체를 피드백할 수 있는 구조는 ‘나중에’ 설계해야 한다
자동화 시스템이 결과를 내기 시작하면, 그 결과를 다시 사람이 확인하고 평가하고 수정하는 피드백 루프가 필요해진다. 그러나 이 구조를 너무 일찍부터 설계하려 하면, 마치 실이 엉켜 있는 상태에서 한 번에 다 풀려는 것처럼 일이 더 꼬이게 된다.
처음부터 자동화 피드백 구조까지 생각하면, 오히려 정작 자동화도 못 하고, 검수도 못 하게 되는 경우가 많다. 자동화는 먼저 단순한 출력이라도 안정적으로 만들어내는 게 핵심이고, 그 뒤에야 비로소 사람이 "이건 잘됐고, 이건 아니다"라고 판단할 수 있다.
피드백 구조를 만드는 최적의 타이밍은, 사람이 실제로 다량의 결과물을 보고 수정을 반복하다가 "이런 걸 계속 하려면 시스템적으로 정리해야겠다"는 필요가 생겼을 때다. 즉, 사람의 작업량이 임계점을 넘었을 때 피드백 구조를 설계하고, 나아가 그 피드백 자체도 자동화하는 방향으로 발전시키는 것이 이상적이다.
지금 디깅 뮤직에서는 AI가 생성한 결과에 모두 ai 태그를 달고, 입력값(input), 생성된 출력값(output), 그리고 사람이 해당 결과를 검토했는지 여부까지 DB에 저장하고 있다. 이 구조는 DPO 학습이나 파인튜닝을 위한 데이터 수집에 굉장히 효과적이다.
그러나 이 구조조차도 처음부터 설계한 건 아니다. 자동화된 결과가 쌓이고, 그걸 사람이 반복적으로 고치다 보니 자연스럽게 생긴 구조다.
요약하자면, 자동화를 검토하고 평가하고 개선하는 구조는 당연히 필요하지만, 그건 자동화가 일정 수준에 도달한 ‘다음’ 단계에서 설계해야 할 일이다.
5. 비선형적인 사고 흐름을 자동화할 수 있는가?
사람의 많은 업무는 비선형적이다. 절차가 정해져 있다 하더라도, 중간에 판단이 바뀌어 흐름을 셧다운하거나 되돌리는 일이 빈번하다. 비선형적이라는 건 단순히 순서를 바꾸는 것을 넘어, 현재의 정보가 과거의 판단을 수정하게 만든다는 점에서 중요하다.
그렇다면 이런 비선형적인 흐름은 자동화될 수 있을까?
우선, 절차가 필요한 이유는 명확하다. 사람이나 AI 모두 큰 덩어리의 문제를 한 번에 처리하는 데에는 한계가 있기 때문이다. 절차를 나누는 이유는 결국 부담을 쪼개기 위한 것이며, 이는 자동화에서도 마찬가지다.
최근에는 LLM의 비선형적 태스크 처리를 위한 다양한 접근이 시도되고 있다. 대표적인 예가 바로 Function Calling이다. LLM이 언어 생성 대신, 외부 함수를 호출하는 방식으로 작업을 분리하고 관리할 수 있게 만든 구조다. 각 함수는 모듈화되어 있고, 입력값에 따라 명확한 출력을 내므로 전체 흐름이 추적 가능해진다.
더 나아가, 나는 다음과 같은 구조를 떠올렸다:
- 전체 업무 흐름을 관리하는 메타인지적 AI가 존재한다.
- 이 AI는 각각의 세부 태스크(번역, 해설, 검토 등)에 맞는 함수나 튜닝된 모델들에게 적절한 인풋을 제공한다.
- 각 서브 시스템은 그 인풋을 바탕으로 결과를 생성하고, 메타 AI는 이 결과들을 종합해 다음 단계를 판단하거나 루프를 되돌린다.
이러한 구조는 현재 'MoE(Mixture of Experts)'나 'Router-based LLM'이 지향하는 바와도 맞닿아 있다. 다양한 전문성을 가진 모듈이 있고, 상황에 따라 적절한 모듈이 선택되는 구조 말이다.
현실의 물리적 작업 예를 들어 제조업에선 이와 비슷한 고민이 더 오래전부터 존재했다. 포드의 컨베이어 벨트는 전형적인 선형 공정이며, 이는 일관된 결과물을 찍어내는 데에는 최적화되어 있다. 그러나 맞춤형 제품이나 커스터마이징이 필요한 공정에서는 비선형적 의사결정이 필연적으로 개입된다.
예를 들어 모듈러 주택을 만든다고 하자. 초기에 고객과 구조 설계를 한 뒤, 내부 자재를 고르고 배치를 고민하는 과정에서 다시 구조 설계를 수정해야 하는 상황이 발생할 수 있다. 이때 자동화 시스템이 이전 단계로 돌아가고, 다시 전체 플로우를 재조정할 수 없다면, 사람의 개입 없이는 오류를 피할 수 없다.
이러한 문제를 해결하기 위해선, 상태 기반 흐름 관리(State Machine), 조건부 분기, 롤백 가능한 구조 등이 도입되어야 한다. 그리고 궁극적으로는, 메타인지적 판단을 모방하는 AI가 전체 흐름을 제어하고, 실패했을 때만 사람이 개입하는 “조정자-대리인” 구조로 가는 것이 가장 실용적일 것이다.
요약하자면, 비선형 흐름은 자동화가 어렵지만, 선형 구조의 조합, 함수화된 모듈, 메타 레벨의 판단 로직을 활용해 어느 정도 근접할 수 있다. 이 가능성은 현재의 Function Calling이나 MoE 아키텍처, 그리고 스마트 공장 등에서 서서히 구현되고 있다.
'프로젝트 > 디깅 - 종합음악플랫폼' 카테고리의 다른 글
[디깅 뮤직 25편] UI, UX, DB개선 (1) | 2025.06.30 |
---|---|
[디깅 뮤직 24편] 구글 애널리틱스 (0) | 2025.06.30 |
[디깅 뮤직 23편] 디깅 뮤직을 오픈까지 하면서 느낀점 (1) | 2025.06.19 |
[디깅 뮤직 22편] 사이트 오픈 (1) | 2025.06.19 |
[디깅 뮤직 21편] 문제 해결보다 먼저 해야 할 생각 전환 (1) | 2025.06.11 |