AI 도구 신기능 풀이

잘게 쪼개 병렬로 돌렸더니 정확히 거꾸로였다 — 호출당 고정비 68초

LLM 호출당 고정비용 68초를 계측한 뒤 분할·병렬화 전략을 뒤집어 6분 4초짜리 단계를 2분 53초로 줄인 최적화 회고입니다.


제가 만든 영상 렌더 파이프라인에는 LLM에게 화면 위 시각요소의 위치를 잡게 하는 단계가 있습니다. 자막, 강조 박스, 캡션 같은 것들을 어디에 놓을지 결정하는 일인데, 이 한 단계가 6분 4초를 잡아먹었습니다. 전체 렌더 시간에서 가장 크게 튀는 구간이라, 여기만 손보면 체감이 확 달라질 상황이었습니다.

처음 떠올린 방법은 교과서적이었습니다. 영상을 여러 구간으로 나눠서, 각 구간의 배치를 따로 계산하고, 그걸 병렬로 돌리는 것. 쪼개면 한 번에 처리할 양이 줄고, 병렬로 돌리면 벽시계 시간이 줄어드니까요. 그렇게 고쳐서 다시 재 보니 4분 29초가 나왔습니다. 줄긴 줄었습니다. 그런데 이상했습니다. 구간을 여러 개로 나눠 동시에 돌렸는데 이 정도밖에 안 줄어든다는 게 계산과 맞지 않았습니다.

계측을 심고 나서야 보인 것

감으로 더 쪼개 보기 전에, 호출 하나가 실제로 어디서 시간을 쓰는지 재기로 했습니다. 호출 직전과 직후에 타임스탬프를 찍고, 그 안에서 실제 생성에 걸린 시간을 따로 뽑았습니다. 숫자를 보고 나서야 제가 무엇을 하고 있었는지 알았습니다.

호출 1회당 고정비용이 약 68초였습니다. CLI를 기동하고, 시스템 프롬프트와 맥락을 읽어 들이는 데 드는 시간입니다. 그리고 정작 구간 하나의 배치를 실제로 생성하는 데 걸린 시간은 약 1.9초에 불과했습니다. 다시 말해, 한 번 호출할 때마다 68초를 내고 1.9초짜리 일을 시키고 있던 겁니다.

그러자 앞의 결과가 전부 설명됐습니다. 구간을 잘게 쪼갤수록 호출 횟수가 늘고, 호출이 늘수록 저 68초를 그만큼 더 내고 있었습니다. 분할은 처리량을 줄인 게 아니라 고정비를 인원수만큼 복사하고 있었고, 병렬화는 그 늘어난 손해를 겨우 상쇄해 4분 29초라는 어중간한 숫자를 만들어 낸 것이었습니다. 제가 최적화라고 믿었던 방향이 정확히 거꾸로였습니다.

방향을 뒤집다

고정비가 이렇게 지배적이면 규칙은 단순해집니다. 호출 횟수를 늘리는 모든 선택은 손해입니다. 그래서 쪼개는 방향을 반대로 돌렸습니다. 구간을 잘게 나눠 호출 수를 늘리는 대신, 청크 수를 동시 실행 수에 맞췄습니다. 즉 나눈 조각을 한 물결에 다 태워 동시에 처리하고, 물결을 여러 번 반복하지 않는 구조로 바꿨습니다.

이게 가능했던 이유가 하나 더 있습니다. 이 단계는 CPU 사용률이 5% 수준이었습니다. 실제 무거운 연산은 LLM 쪽에서 일어나고 제 서버는 호출을 던져 놓고 기다리기만 하므로, 여러 개를 동시에 띄워도 서버 부하가 사실상 0이었습니다. 부하 걱정 없이 물결의 폭을 넓힐 수 있으니, 물결 수를 줄이는 선택에 제약이 없었습니다.

바꾸고 다시 재 보니 2분 53초가 나왔습니다. 원래의 6분 4초 대비 52% 단축입니다. 잘게 쪼개 병렬로 돌리던 4분 29초보다도 한참 아래였습니다. 코드가 더 복잡해진 것도 아니고, 오히려 구간을 잘게 관리하던 로직이 사라지면서 단순해졌습니다.

정리

이 일에서 제가 챙긴 판단 기준은 하나입니다. 병렬화를 손대기 전에, 호출당 고정비부터 재라는 것.

분할과 병렬화는 처리량이 지배적일 때 효과가 있습니다. 작업 하나하나가 실제로 오래 걸리고, 그걸 여러 갈래로 나눠 동시에 흘려보낼 때 시간이 줄어듭니다. 하지만 작업 단위당 고정비가 실제 처리 시간보다 크면 이야기가 반대가 됩니다. 68초를 내고 1.9초짜리 일을 시키는 구조에서 조각을 늘리는 건 최적화가 아니라 비용입니다. 병렬화는 그 비용을 잠깐 가려 줄 뿐, 없애 주지는 않습니다.

그래서 다음에 느린 구간을 만나면, 저는 먼저 쪼갤 궁리를 하지 않고 호출 하나가 어디에 시간을 쓰는지부터 잽니다. 지배적인 비용이 고정비인지 처리량인지, 그 한 줄만 확인해도 방향이 정해집니다. 계측 없이 감으로 쪼갰다면 저는 더 잘게 나누며 68초를 계속 복사하고 있었을 겁니다.

자주 묻는 질문

LLM 호출을 잘게 쪼개 병렬로 돌리면 항상 빨라지나요?

아닙니다. 호출당 고정비용이 실제 생성 시간보다 크면, 쪼갤수록 고정비를 더 내게 됩니다. 병렬화는 그 손해를 상쇄할 뿐이라 기대만큼 줄지 않습니다. 분할 전에 호출 1회의 고정비부터 재는 것이 먼저입니다.

LLM 호출의 고정비용은 어떻게 측정하나요?

호출 직전과 직후에 타임스탬프를 찍어 총 소요를 재고, 실제 생성에 걸린 시간과의 차이를 봅니다. 이 차이가 CLI 기동, 시스템 프롬프트·맥락 처리 같은 고정비입니다. 제 경우 호출당 약 68초였고 구간당 실제 생성은 약 1.9초뿐이었습니다.

고정비가 지배적일 때 병렬화는 어떻게 설계해야 하나요?

분할 수를 늘리는 대신 청크 수를 동시 실행 수에 맞춰 한 물결로 처리하는 방식이 유리합니다. 이 단계는 CPU 사용률이 5% 수준이라 동시에 여러 개를 띄워도 서버 부하가 사실상 없었기에, 물결 수를 줄이는 방향이 그대로 시간 단축으로 이어졌습니다.

병렬화가 최적화가 아니라 비용이 되는 경우는 언제인가요?

작업 단위당 고정비가 실제 처리 시간보다 클 때입니다. 이때 분할은 병렬로 감출 수 없는 고정비를 인원수만큼 늘리는 행위가 됩니다. 지배적인 비용이 고정비인지 처리량인지부터 계측해야 방향을 정할 수 있습니다.

#LLM#병렬화#성능 최적화#1인 개발#하네스