Action 2/2

LLM 추론 환경 구축

아키텍처 전체 설계는 사내 시니어 엔지니어와의 협업으로 진행했고, 저는 검수 대상 채팅 정보를 수집하는 Batch Job 구현과 LLM Worker 내의 추론 파이프라인 구현을 담당했습니다.

Batch Job

sequenceDiagram
    autonumber
    participant Scheduler as Airflow
    participant Batch as Batch Job
    participant Athena
    participant SQS

    Scheduler->>Batch: 매 시간 트리거
    Batch->>Athena: 검수 대상 채팅 정보 요청
    Athena-->>Batch: 검수 대상 채팅 메타데이터<br/>(ex. 채팅방 ID, 시작/끝 시간)
    Batch->>SQS: 메타데이터를 담은 이벤트 publish
          

채팅 로그는 사내 데이터 레이크하우스에 이미 적재되고 있어서 Athena를 통해 조회했습니다. 배치 호출에 머무를 예정이었다면 매 시간 수집한 채팅 정보를 S3에 업로드하고 이를 트리거로 LLM 워커를 실행하는 방식이 단순했겠지만, 궁극적으로 실시간 추론으로 전환할 계획이었기 때문에 이벤트 스트림 기반 아키텍처가 채택됐습니다. 워커가 SQS를 구독하고 있는 구조를 만들어두면 실시간 추론으로 전환할 시점에 이벤트 publisher만 이 배치에서 채팅 서비스의 이벤트 발행 로직 등으로 적절히 변경하면 되기 때문입니다. 또한, 파이프라인 태스크들이 하나의 워커에서 순차 실행되는 구조라서 subscriber가 하나이고, 이벤트가 하나의 독립된 채팅 히스토리 단위라 순서 보장도 불필요했기 때문에, broker 서비스로 Kinesis Data Streams나 SQS FIFO 대신 표준 SQS가 선택됐습니다.

LLM Worker

sequenceDiagram
    autonumber
    participant SQS
    participant Worker as LLM Worker
    participant Buntalk as 번개장터 API
    participant LLM as LLM Endpoint
    participant DB as MySQL

    Worker->>SQS: long-poll
    Worker->>Buntalk: 이벤트에 대응되는 채팅 히스토리 GET
    Buntalk-->>Worker: 채팅 히스토리 (수령 후 전처리)

    loop 추론 파이프라인 (4-stage task)
        Worker->>LLM: 채팅 히스토리
        LLM-->>Worker: 태스크별 추론 결과
    end

    Worker->>DB: 어뷰징 여부 검수 결과 upsert
    Worker->>SQS: 해당 이벤트 삭제
          

SQS에 발행된 이벤트는 LLM 워커가 구독하여 다이어그램에 묘사된 순서로 처리합니다. 이 워크플로는 신뢰성, 확장성, 장애 대응 세 축에서 다음과 같이 설계되어 있습니다.

  1. 중복 처리 방지 : 파이프라인에서 한 이벤트를 처리할 때 LLM을 여러 번 호출하며 소요 시간이 길어질 수 있기 때문에, SQS의 visibility timeout을 충분히 길게 설정하여 한 이벤트가 중복으로 처리되는 케이스를 방지했습니다.
  2. 스케일링 : 이벤트가 가장 적게 발행되는 시간대 대비 피크타임에는 처리해야 할 이벤트가 최대 20배 가까이 늘어나지만, LLM 워커 Pod 자체의 리소스 요구량이 매우 낮기 때문에 오토스케일링 없이 피크 트래픽에 맞춰 Pod을 실행시켜 두었습니다.
  3. 장애 허용 : 오픈소스 LLM 추론 엔드포인트가 모종의 이유로 응답하지 않을 시 PoC 과정에서 성능 테스트를 완료한 외부 LLM API 엔드포인트를 호출하도록 fallback을 설정했습니다.

LLM Endpoint

기능이 최초로 도입될 때는 오픈소스 LLM 추론에서 오는 운영 부담을 없애기 위해 LLM 엔드포인트는 매니지드 서비스로 운영하고 있었습니다. 하지만 이 서비스가 현재 사양의 하드웨어 지원을 종료하고 상위 스펙으로의 강제 마이그레이션을 올해 말 예고하면서, 서비스 제공자의 로드맵 변화에 따른 요금 체계나 예상 성능 변화에 수동적으로 종속되는 리스크를 인지하게 되었습니다. 통제 가능한 런타임을 확보하기 위한 대안을 검토하기 위해, 동일 오픈소스 LLM을 GPU 인스턴스에서 실행되는 vLLM 컨테이너 안에서 자체 서빙하는 구성을 매니지드 서비스와 성능·품질 관점에서 비교하는 벤치마크를 진행했습니다. 자체 구성은 quantization 여부에 따라 BF16과 FP8 두 setup을 함께 측정해, 총 3개 setup을 비교했습니다.

Setup하드웨어양자화
매니지드 서비스 (기준)NVIDIA A100미공개
BF16NVIDIA RTX PRO 6000 Blackwell없음
FP8NVIDIA RTX PRO 6000 BlackwellFP8

성능 관점에서는 자체 구성이 매니지드 서비스 대비 유의미하게 빠르게 측정되었습니다.

Setupwall time 단축tok/s 배율
매니지드 서비스 (기준)1.00×
BF1646% 단축1.68×
FP860% 단축2.31×

추론 파이프라인 내 태스크별 wall time 격차를 분해해보니 이미지 처리가 필요한 task에 격차가 집중되어 있었습니다. 이 태스크만 유독 p50 TTFT가 다른 setup들에 비해 몇 배 차이나는 반면 텍스트만 처리하는 태스크들의 TTFT 격차는 비교적 일정했습니다. 매니지드 서비스는 한국 리전에서 서비스를 제공하지 않았기 때문에, 이 격차는 매니지드 서비스에서 이미지 URL을 fetch하며 발생하는 네트워크 비용이라고 판단했습니다. 매니지드 서비스가 리전 선택권을 제공하지 않는 한 이 격차는 구조적으로 해소가 어렵다고 결론지었습니다.

SetupPrecisionRecallF1
매니지드 서비스 (기준)
BF16+0.7pt-4.2pt-2.4pt
FP8-1.8pt+0.8pt-0.3pt

품질 관점에서는 세 setup이 오차 범위 내에서 동일한 성능을 보인다고 판단해서, 매니지드 서비스에서 FP8 양자화를 적용한 자체 서빙 setup으로의 마이그레이션이 효과적이라는 결론을 내렸습니다. 또한, 현재는 벤치마크를 진행할 당시와는 달리 vLLM 이미지에서 이 LLM에 대한 speculative decoding(MTP)을 지원하고 있습니다. 매니지드 서비스에서는 이런 최적화 옵션 도입 여부와 시점이 전적으로 제공자의 로드맵에 종속된다는 점도 마이그레이션을 긍정적으로 고려할만한 지점이 되었습니다. 아직까지는 매니지드 서비스가 더 가격 경쟁력이 있어서 마이그레이션을 급하게 시도하지는 않고 있지만, 예고된 강제 마이그레이션이 실행되는 시점에는 이 벤치마크 결과를 근거로 자체 서빙으로 전환할 계획입니다.