UnitBoost, 합성 LLM 시스템을 모델이 아니라 병합 연산자로 관리하기

생성형 관리자 대신 단위 지도와 제약 argmax 조립, 잔여분 지정으로 합성 LLM 시스템을 관리하는 UnitBoost의 구조와 실험 결과를 해설합니다.

원문 논문 보기
'UnitBoost, 합성 LLM 시스템을 모델이 아니라 병합 연산자로 관리하기' 기사 커버 이미지

arXiv에 공개된 UnitBoost: Managing Compound LLM Systems with a Merge Operator, Not a Model(2609.09815)은 compound LLM 시스템의 조정 문제를 생성형 관리자 모델 하나로 떠맡기지 말고 정의된 병합 연산자로 풀자고 제안합니다. 원문 링크는 제목 아래 걸어두었습니다.

이 글에서는 그 연산자가 무엇으로 이뤄졌는지, 왜 순서 불변과 출처 기록을 얻는 대신 의미적 자유를 내려놓는지, 그리고 세 개의 held-out 벤치마크에서 왜 oracle 단일 후보와 입력이 같은 생성형 관리자보다 앞섰는지를 차례로 풀어보겠습니다.

왜 관리자 모델이 계속 신경 쓰였을까

제가 이 논문에서 가장 흥미롭게 본 부분은 문제 설정 자체였습니다. 여러 LLM을 한 시스템으로 묶으면 누군가는 흩어진 출력을 모아야 하는데, 그동안 그 역할을 당연하다는 듯이 더 큰 LLM에게 맡겨왔습니다. 작업자 모델들이 각자 답을 내놓으면 관리자 모델이 최종 답을 쓰고, 다음 호출을 배분하고, 언제 멈출지도 정하는 방식이죠. 언뜻 보면 자연스럽습니다. 언어를 이해하는 존재에게 언어로 된 출력을 정리시키니까요.

그런데 실제 시스템을 오래 보다 보면 여기서 묘한 불안이 생깁니다. 관리자가 똑똑해질수록 최종 답의 품질은 올라가지만, 왜 그런 답이 나왔는지는 점점 설명하기 어려워지기 때문입니다. 같은 입력에 같은 작업자를 붙여도 관리자 한 줄의 말투가 바뀌면 결과가 달라지는 경우도 있고, 작업자 중 누가 어떤 조각에 기여했는지 나중에 추적하기 어려운 경우도 많습니다. 그렇다면 관리를 꼭 생성으로 해야 할까요? 이 질문이 저를 이 논문으로 끌어들였습니다.

저희가 새로운 AI 아키텍처를 볼 때도 benchmark 숫자만 보지는 않습니다. 실제로 무엇이 바뀌었고, 그 변화가 시스템에서 어떤 비용 구조를 만드는지를 함께 봅니다. 그런 눈으로 보면 UnitBoost는 숫자를 올리는 기법이라기보다 책임의 위치를 옮기는 제안에 가깝습니다. 이해와 판단은 작업자에게 두고, 모으는 일은 규칙으로 고정하겠다는 것이죠.

여러 모델을 붙이면 조정자가 필요해진다

여러 사람이 함께 일하다 보면, 누군가의 말 한마디가 팀 전체의 분위기를 바꾸기도 합니다. 그렇다면 여러 AI가 한 팀으로 일할 때도 비슷한 일이 생길까요? compound 시스템에서는 이 질문이 곧바로 설계 문제로 바뀝니다. 각자 잘하는 모델을 모아놓으면 개별 능력은 좋아지는데, 그 사이를 누가 메울지가 남기 때문입니다.

일반적인 해법은 위에서 한 층을 더 올리는 것이었습니다. 작업자 출력들을 읽고 최종 답을 새로 쓰는 상위 LLM을 두는 것이죠. 이 관리자는 읽고 쓰는 일을 동시에 합니다. 흩어진 문장들을 매끄럽게 잇고, 모순을 정리하고, 부족하면 추가 호출을 지시합니다. 표현력이 풍부하다는 장점이 분명히 있습니다. 어떤 작업자가 엉뚱한 말을 해도 관리자가 문맥으로 수습할 수 있으니까요.

문제는 그다음입니다. 관리자가 새로 쓴 문장은 원래 작업자 출력과 일대일로 대응되지 않습니다. 어느 문장이 누구에게서 왔는지 흐려지고, 입력 순서를 바꾸면 출력이 미묘하게 바뀌기도 합니다. 밤늦게 장애 로그를 보다가 "이 답이 왜 이렇게 됐지?"라고 물을 때, 생성형 관리자는 대개 그럴듯한 설명을 내놓지만 검증 가능한 기록을 내놓지는 않습니다. 저는 여기서 조금 멈칫했습니다. 똑똑한 조정자가 오히려 시스템의 설명 가능성을 갉아먹고 있는 것은 아닐까 싶어서요.

생성하지 않고 관리할 수는 없을까

여기서 재미있는 질문이 생깁니다. 관리자가 꼭 말을 만들어내야 할까요, 아니면 모아주기만 하면 될까요? UnitBoost의 대답은 후자 쪽에 가깝습니다. 논문은 관리를 생성형 모델이 아니라 정의된 meta-level 연산자로 바꾸자고 말합니다. 새 문장을 짓는 대신, 작업자 출력들을 정해진 슬롯에 넣고 규칙대로 고르는 일이 관리의 전부라는 것이죠.

이 차이는 생각보다 중요합니다. 생성형 관리자는 어떤 말이든 쓸 수 있습니다. 자유롭지만 그만큼 예측하기 어렵습니다. 반면 병합 연산자는 할 수 있는 일이 정해져 있습니다. 작업자가 내놓은 조각들을 단위로 나누고, 허용된 조합 안에서 점수가 가장 높은 조립을 고르고, 다음 라운드에 무엇을 더 채워야 할지를 적어둡니다. 마치 여러 사람이 가져온 퍼즐 조각을 책상 위에 펼쳐놓고, 빈칸 모양에 맞는 조각만 끼우는 일과 비슷합니다.

개인적으로는 이 대비가 마음에 들었습니다. 능력을 키우는 방향이 아니라 권한을 줄이는 방향에서 답을 찾았기 때문입니다. 물론 권한을 줄이면 표현이 투박해질 수 있습니다. 매끄러운 요약문 대신 뚝딱거리는 조립 결과가 나올 수도 있죠. 그런데 논문은 그 투박함을 감수할 만한 값어치가 있다고 말합니다. 순서가 바뀌어도 결과가 바뀌지 않고, 각 조각이 어디서 왔는지 남으며, 실패 조건을 미리 시험할 수 있기 때문입니다.

이 아이디어가 아닌 것들을 먼저 덜어내면

이런 설명을 들으면 reranking이나 voting을 떠올리신 분도 계실 것 같습니다. 실제로 후보 여러 개를 놓고 가장 좋은 하나를 고르는 일은 오래된 기법이죠. 그런데 UnitBoost가 하려는 일은 그와 결이 다릅니다. 후보 통째로 하나를 고르는 게 아니라 후보들을 잘게 나눠서 좋은 조각끼리 새로 엮는 일이기 때문입니다.

router나 MoE의 gating과도 다릅니다. 그런 구조는 입력을 보고 어디로 보낼지를 정하는 데 집중합니다. 반면 UnitBoost의 연산자는 이미 나온 출력들을 어떻게 합칠지를 정합니다. 호출 전에 길을 고르는 일이 아니라 호출 뒤에 결과를 엮는 일이죠. 그래서 이 연산자는 작업자 모델을 바꾸지 않고도 얹을 수 있습니다. 엔진을 통째로 교체하는 게 아니라 조립대만 바꾸는 셈입니다.

또 하나 짚을 점은 이 연산자가 학습된 모델이 아니라는 것입니다. 프롬프트를 잘 써서 관리자를 흉내 내는 방법도 아니고, 별도 보상 모델을 붙이는 방법도 아닙니다. 과제에서 주어진 단위 정의에 따라 제안을 슬롯에 넣고, 정해진 점수로 조립을 고릅니다. 저는 이 지점이 오해를 막는 데 도움이 된다고 봅니다. 이름에 Boost가 들어가서 부스팅처럼 들리지만, 실제로는 가중치를 차례로 고치는 학습 알고리즘이 아니라 매번 같은 규칙으로 합치는 연산자에 가깝기 때문입니다.

제안하고 고르고 남기는 세 단계

그렇다면 연산자는 실제로 어떻게 움직일까요? 흐름을 따라가 보면 세 단계로 나눌 수 있는데, 각 단계가 맡은 일이 분명합니다. 먼저 task-given unit map이 작업자 출력들을 슬롯과 값의 제안으로 바꿉니다. 예를 들어 표 채우기 과제라면 셀이 슬롯이 되고, 작업자가 적은 셀 값이 제안이 됩니다. 단위의 정의를 논문이 새로 만드는 게 아니라 과제가 주기 때문에, 무엇을 쪼갤지를 두고 다툴 일이 줄어듭니다.

다음은 제약이 걸린 argmax 조립 단계입니다. 모든 슬롯에 대해 같은 허용 점수로 각 제안을 평가한 뒤, 결합 제약을 만족하는 조합 중에서 점수 합이 가장 높은 조립을 고릅니다. 여기서 제약이라는 말이 어렵게 들릴 수 있는데, 실제로는 "이 두 값은 같이 쓸 수 없다" 같은 현실적인 조건을 뜻합니다. 서로 모순되는 셀 값은 함께 뽑지 못하게 막는 것이죠. 허용 점수가 같다는 조건도 눈여겨볼 만합니다. 평가 기준을 하나로 고정해두니 나중에 결과를 복기할 때 "이 조각이 뽑힌 이유"를 물을 수 있게 되기 때문입니다.

마지막은 다음 라운드를 위한 잔여분(residual)입니다. 다 채우지 못한 슬롯, 점수가 아슬아슬한 슬롯, 서로 다투는 제안이 있는 슬롯을 그대로 다음 호출의 목표로 적어둡니다. 저는 이 대목에서 무릎을 쳤습니다. 보통은 "한 번 더 읽어봐"라고 두루뭉술하게 시키는데, 여기서는 무엇이 비었는지를 정확히 적어서 다음 라운드에 넘기기 때문입니다. (참고로 이 잔여분 개념은 부스팅의 잔차 아이디어를 닮았는데요. 틀린 부분을 다음 단계가 메우도록 목표를 넘긴다는 점에서 그렇습니다.)

순서를 잊고 출처를 기억하는 방식

이 구조가 주는 선물은 두 가지인데, 둘 다 운영해본 사람에게는 꽤 크게 다가옵니다. 하나는 순서 불변(order invariance)이고, 다른 하나는 단위 출처(unit provenance)입니다. 작업자 출력을 어떤 순서로 넣어도 조립 결과가 달라지지 않으며, 최종 답의 각 조각이 어느 작업자 제안에서 왔는지 그대로 남습니다. 입력 순서를 바꾸면 답이 살짝 바뀌는 생성형 관리자와는 정반대의 성질이죠.

왜 이렇게 될까요? 이유는 연산자가 문장을 읽는 순서에 의존하지 않기 때문입니다. 슬롯별로 제안을 모아 점수를 매기고 가장 좋은 것을 고르는 일은 순서를 섞어도 결과가 같습니다. 카드 뭉치를 아무리 섞어도 각 숫자별로 가장 큰 카드를 뽑으면 손패가 같아지는 것과 비슷합니다. 반면 생성형 관리자는 앞에서 읽은 문장에 더 끌리거나 뒤에서 읽은 문장으로 결론을 덮는 식의 순서 효과를 피하기 어렵습니다.

출처 기록도 같은 뿌리에서 나옵니다. 새로 문장을 짓지 않고 기존 제안을 고르기만 하니 "이 셀 값은 두 번째 작업자가 낸 것이다"라는 기록이 자연스럽게 남습니다. 장애 대응을 생각하면 이 차이가 큽니다. 새벽에 잘못된 답이 나갔을 때 "관리자가 그렇게 썼다"는 말과 "이 슬롯의 제안 점수와 채택 기록은 여기 있다"는 말은 무게가 다르니까요. 물론 의미적 자유를 포기한 대가도 있습니다. 작업자가 아무도 말하지 않은 내용을 관리자가 덧붙여 줄 수는 없습니다. 저는 이 교환이 정직하다고 봅니다. 말솜씨를 희생하고 검증 가능성을 샀기 때문입니다.

가장 잘 고른 하나보다 잘게 쪼개 고른 쪽이 이긴다

여기까지는 설계 이야기였고, 이제는 숫자를 볼 차례입니다. 그런데 이 숫자는 그대로 믿기 전에 조건을 봐야 합니다. 논문이 내세우는 보장은 결합 제약이 없을 때, 같은 허용 점수 아래에서는 단위별 최대화가 어떤 완성형 후보 하나를 고르는 것보다 항상 낫다는 것입니다. 각 슬롯에서 가장 좋은 조각을 고른 조립이, 통째로 가장 좋아 보이는 후보 하나보다 점수에서 뒤지지 않는다는 뜻이죠.

처음 들으면 너무 당연해서 "그게 무슨 보장인가?" 싶을 수도 있습니다. 하지만 곰곰이 보면 이 보장이 말하는 바가 있습니다. 완성형 후보 고르기는 좋은 조각과 나쁜 조각을 묶음으로 사야 하는 일입니다. 한 후보의 전반부는 훌륭한데 후반부가 틀렸다면, 통째 고르기에서는 그 후반부까지 함께 떠안아야 합니다. 반면 단위별 조립은 전반부는 이 후보에서, 후반부는 저 후보에서 가져올 수 있습니다. 묶음 구매와 낱개 구매의 차이와 비슷합니다.

실험 결과도 이 방향을 가리킵니다. 세 개의 held-out 벤치마크에서 UnitBoost는 정답 라벨로 고른 가장 좋은 단일 후보(oracle)보다 0.060에서 0.195만큼 절대 점수로 앞섰고, 입력이 같은 생성형 관리자보다는 0.048에서 0.076만큼 앞섰습니다. 특히 oracle을 앞섰다는 대목이 눈에 띕니다. 정답을 보고 고른 하나의 답보다, 조각을 엮은 답이 더 좋았다는 뜻이기 때문입니다. 저는 이 숫자보다 그 뒤의 구조가 더 중요하다고 봅니다. 이김의 이유가 더 큰 모델이 아니라 더 잘게 나누는 규칙에 있었기 때문입니다.

관리 단계만 갈아 끼웠는데 여섯 구성이 달라진다

좋은 건 알겠는데, 이걸 실제로 어떻게 얹을까요? 논문이 준비한 답은 꽤 실용적입니다. 작업자 모델과 호출 예산은 그대로 두고, 관리 단계만 이 연산자로 교체하는 실험을 여섯 가지 compound 구성에 적용했습니다. 결과는 0.013에서 0.182까지의 개선이었습니다. 구성이 모두 다르다는 점을 생각하면, 어느 한 세팅에만 붙는 요행이 아니라는 느낌이 듭니다.

여기서는 조금 조심해서 읽을 필요가 있습니다. 개선 폭이 구성마다 꽤 벌어지기 때문입니다. 어떤 구성에서는 작은 손질 수준이었고, 어떤 구성에서는 흐름을 바꾸는 수준이었습니다. 논문도 이를 숨기지 않습니다. 작업자 출력의 다양성과 단위 정의의 선명도에 따라 이득이 달라질 수밖에 없기 때문입니다. 다들 비슷한 말만 내놓는다면 쪼개서 고를 것도 없고, 단위가 흐릿하면 어디에 무엇을 넣을지도 정하기 어렵습니다.

그렇다면 이 흐름은 어디서 더 확인할 수 있을까요? 잔여분이 이끄는 반복 라운드가 그 다음 장면입니다. FanOutQA의 셀 F1이 0.4778에서 0.5524로 올랐는데, 진짜 잔여분을 목표로 삼은 라운드가 무작위 목표나 보통의 다시 읽기를 앞섰습니다. 빈칸을 정확히 찔렀을 때와 막연히 다시 읽혔을 때의 차이가 숫자로 드러난 셈입니다. 일반 파일에만 남겼을 때는 효과가 작았지만, 다음 라운드 입력에 직접 들어가는 잔여분은 달랐다는 점도 함께 기억할 만합니다. 다음 호출이 무엇을 봐야 하는지가 분명할수록 라운드는 헛돌지 않기 때문입니다.

다음 라운드에 무엇을 시킬지 적어두는 잔여분

잔여분 이야기가 나왔으니 조금 더 들어가 보겠습니다. 이 개념이 좋은 이유는 다음 호출을 추측이 아니라 기록으로 움직이게 만들기 때문입니다. 보통 멀티 라운드 시스템에서는 첫 라운드 답을 보고 "부족한 것 같으니 한 번 더"라고 말합니다. 그런데 무엇이 부족한지는 관리자 머릿속에만 있습니다. UnitBoost에서는 그 부족함이 슬롯 단위로 적힙니다. 어느 셀이 비었고, 어느 셀에서 제안들이 다투고, 어느 셀의 점수가 낮은지가 다음 라운드의 입력이 되는 것이죠.

이 차이는 라운드가 거듭될수록 벌어집니다. 막연한 다시 읽기는 매번 비슷한 답을 되돌려줄 수 있지만, 잔여분 지정 다시 읽기는 매번 다른 질문을 던집니다. 처음에는 비어 있던 셀이 채워지고, 다음에는 다투던 셀이 정리되는 식입니다. 생각해보면 사람도 비슷하게 배웁니다. 오답 노트에 "분수 계산에서 자꾸 틀린다"고 적어두면 다음 공부가 달라지듯이요.

물론 잔여분이 만능은 아닙니다. 작업자가 애초에 모르는 내용을 슬롯에 적어둘 수는 없기 때문입니다. 잔여분은 어디를 더 파야 할지를 알려줄 뿐, 땅속에 무엇이 있는지를 바꿔주지는 않습니다. 그럼에도 저는 이 장치를 좋게 평가했습니다. 라운드 사이의 연결이 말로만 이어지는 게 아니라 문서로 이어지기 때문입니다. 나중에 "2라운드에서 왜 그 호출을 했나?"라고 물으면 잔여분 기록을 펼치면 됩니다.

도움이 되지 않는 경우도 분명히 있다

이제까지의 이야기를 듣고 "그럼 언제나 쓰면 되는 것 아닌가?"라고 물을 수도 있습니다. 논문이 솔직한 지점은 바로 여기입니다. 이득이 없는 세 가지 조건을 미리 정의해두었기 때문입니다. 첫째는 나눌 수 없는 단위 하나짜리 과제이고, 둘째는 단위 식별이 불가능한 경우이며, 셋째는 내보내는 단위마다 요금을 매기는 엔드포인트입니다.

각 조건을 풀어보면 납득이 됩니다. 답이 통째로 하나라서 쪼갤 수 없다면 조립할 것도 없습니다. 통째 답을 고르는 일과 단위 조립이 같아지기 때문입니다. 단위 식별이 안 돼서 어느 조각이 어느 슬롯용인지 알 수 없다면 지도 자체를 그릴 수 없습니다. 그리고 내보낼 때마다 과금되는 구조에서는 조각을 많이 내는 일이 곧바로 비용이 됩니다. 아낀 호출로 얻는 이득보다 배출 비용이 커질 수 있는 것이죠.

저는 이런 실패 조건의 명시가 오히려 신뢰를 높인다고 봅니다. 언제나 좋다는 말은 검증할 수 없지만, 언제 안 좋다는 말은 시험할 수 있기 때문입니다. 실제 시스템 관점에서 보면 다음 질문이 바로 생깁니다. 우리 과제의 단위는 무엇이고, 그 식별은 얼마나 안정적이며, 배출당 비용 구조는 어떻게 되는가. 이 질문에 답할 수 있다면 도입 여부를 판단할 수 있고, 답할 수 없다면 아직 도입할 때가 아니라는 뜻이기도 합니다.

검증할 수 있는 구조가 남기는 질문

그래서 이 논문은 무엇을 바꾸는 걸까요? 표면적으로 보면 병합 방식을 바꾸는 제안입니다. 실제로는 평가의 기준을 바꾸는 제안에 가깝습니다. 생성형 관리자가 매끄러운 답을 내놓았을 때 우리는 "잘 읽히네"라고 말합니다. 하지만 UnitBoost가 내놓은 조립을 볼 때는 다른 질문을 던지게 됩니다. 순서가 바뀌어도 같은가, 각 조각의 출처는 무엇인가, 실패 조건에 해당하는가. 읽힘새가 아니라 검증 가능성으로 묻는 것이죠.

질문도 바뀌었습니다. "좋은 관리 프롬프트는 무엇인가?"에서 "좋은 단위 정의와 허용 점수는 무엇인가?"로 말이죠. 전자는 말재주에 기대는 질문이고, 후자는 과제의 구조를 묻는 질문입니다. 저는 이 이동이 compound 시스템의 다음 단계를 가리킨다고 봅니다. 모델이 커질수록 개별 답변은 좋아지는데, 그 답변들을 엮는 일은 오히려 더 어려워지기 때문입니다.

제가 앞으로 보고 싶은 것은 이 연산자가 실제 서빙 흐름에서 어떤 비용 곡선을 그리는지입니다. 슬롯별 점수 계산과 제약 검사가 토큰 비용과 지연에 어떻게 얹히는지, 작업자 수가 늘어날 때 조립 시간이 어떻게 증가하는지, 잔여분 라운드가 평균 호출 횟수를 얼마나 늘리는지가 궁금합니다. 그렇다면 사람의 역할은 무엇일까요. 아마도 단위를 정의하고, 허용 기준을 정하고, 잔여분을 읽는 일이 될 것 같습니다. 말을 잘 짓는 일이 아니라 일을 잘 나누는 일이 남는 것이죠.

참고 자료

  1. UnitBoost: Managing Compound LLM Systems with a Merge Operator, Not a Model · arxiv.org

    리뷰 원문