플래그 하나로 끝내는 vLLM 네이티브 속도 구현

LLM 모델을 vLLM(고성능 추론 엔진) 같은 엔진에서 구동해 비용을 최적화하려는 조직들은 그동안 모델 코드를 직접 포팅(다른 환경에 맞게 수정해 옮기는 작업)해야 하는 번거로움을 겪었다. 450개 이상의 아키텍처를 지원하는 transformers 라이브러리가 표준 레퍼런스 역할을 하지만, 정작 최대 성능을 내려면 vLLM 전용으로 수동 작성된 네이티브 코드가 필요했기 때문이다. Hugging Face는 이러한 수동 최적화 과정 없이도 vLLM의 네이티브 구현체와 동일한 추론 속도를 낼 수 있는 모델링 백엔드를 업데이트했다. 이제 개발자는 복잡한 포팅 작업 없이 설정 하나만으로 인프라 효율을 극대화할 수 있다.

Hugging Face 모델을 vLLM에서 구동할 때 실행 플래그 `--model-impl transformers` 하나만 추가하면 된다. 이 플래그는 기존의 병렬화 옵션과 그대로 조합하여 사용할 수 있으므로, 기존의 서빙 인프라 설정이나 배포 파이프라인을 수정할 필요가 없다.

bash
--model-impl transformers

이 구조에서 transformers는 모델의 구조를 정의하는 모델링 코드를 제공하고, vLLM은 연속 배칭(Continuous Batching, 여러 요청을 효율적으로 묶어 처리하는 기술)과 커스텀 어텐션 커널(GPU 연산 최적화 단위) 같은 고도로 최적화된 추론 기술을 담당한다.

성능 검증을 위해 서로 다른 특성을 가진 Qwen3 모델 3종을 대상으로 비교 테스트를 진행했다. vLLM 개발자가 직접 수동으로 작성한 네이티브 구현체와 이번에 업데이트된 transformers 모델링 백엔드의 속도를 대조했다. 테스트 환경은 코드 경로를 제외한 모든 조건이 동일하게 설정되었으며, 그 결과 transformers 백엔드가 vLLM 네이티브 구현체와 대등한 추론 속도를 달성했다. 이는 최적화를 위해 수동으로 작성했던 커스텀 코드 수준의 성능을 설정값 변경만으로 확보했음을 보여준다. 구체적인 벤치마크 재현 방법은 아래 Gist에서 제공하는 실행 파일을 통해 확인할 수 있다.

benchmark.sh

다만 지원 범위에는 일부 제한이 있다. 선형 어텐션(Linear Attention, 계산 복잡도를 줄여 연산량을 낮춘 어텐션 방식)을 사용하는 모델은 현재 지원 대상에서 제외되었으며, 추후 업데이트를 통해 지원할 예정이다. 또한 Hugging Face Hub 저장소에 모델 코드가 직접 포함된 커스텀 모델의 경우, 라이브러리 규격을 엄격히 준수하여 작성되지 않았다면 정상적으로 작동하지 않을 가능성이 있다. 하지만 표준 규격을 따르는 대다수의 모델이라면 별도의 최적화 코드를 단 한 줄도 작성하지 않고 vLLM의 최대 성능을 이끌어낼 수 있다.

torch.fx와 ast 기반의 동적 레이어 퓨전 메커니즘

모델 하나를 고성능 엔진에서 돌리려고 수천 줄의 구현 코드를 일일이 옮겨 적는 일은 개발자에게 매우 번거로운 작업이다. vLLM 같은 추론 엔진의 성능을 온전히 활용하려면 모델 구조를 해당 엔진의 네이티브 방식에 맞춰 다시 짜야 했기 때문이다. Hugging Face는 이 반복적인 포팅 과정을 자동화하기 위해 transformers 모델링 백엔드에 torch.fx와 ast를 도입했다. 이는 모델 아키텍처가 바뀔 때마다 반복되는 수동 작업의 굴레를 끊는 시도다. 이를 통해 개발자가 모델 코드를 직접 수정하지 않고도 vLLM 네이티브 구현체와 동일한 수준의 추론 속도를 확보하는 구조를 만들었다.

최적화의 첫 단계는 torch.fx를 이용한 정적 분석이다. torch.fx는 코드를 실제로 실행하기 전에 모델의 연산 그래프를 미리 파악하는 정적 분석 도구다. 시스템은 이 도구를 사용해 모델 내부의 연산 흐름을 논리적인 그래프 형태로 그려낸다. 이후 그래프 내에서 최적화가 가능한 알려진 수학적 패턴을 정밀하게 탐색한다. 이 분석 단계 덕분에 모델의 실제 실행 경로를 예측하고 최적의 연산 순서를 결정할 수 있다. 단순히 연산을 나열하는 것이 아니라, 어떤 연산들이 묶였을 때 하드웨어 가속 효율이 높아지는지 분석하여 최적화 대상 지점을 정확히 찾아내는 과정이다.

분석된 패턴을 바탕으로 ast를 사용하여 실제 소스 코드를 즉석에서 수정한다. ast는 소스 코드를 트리 구조로 표현한 추상 구문 트리로, 프로그램의 문법적 구조를 직접 조작할 수 있는 인터페이스를 제공한다. 시스템은 런타임에 이 트리를 조작하여 기존의 개별 연산들을 레이어 퓨전 기술로 그 자리에서 재작성한다. 레이어 퓨전은 여러 개의 연산을 하나의 GPU 커널로 합쳐 계산 효율을 높이는 기술이다. 개별 연산마다 발생하던 메모리 읽기와 쓰기 횟수를 줄임으로써 데이터 전송 병목을 제거하고 연산 속도를 극대화한다.

이 모든 변환 과정은 모델이 메모리에 로드되는 런타임 시점에 동적으로 수행된다. 기존에는 vLLM의 어텐션 구현체만 플러그인 형태로 연결해 효율을 높였으나, 이제는 모델 전체의 연산 구조를 최적화된 형태로 재구성한다. 개발자는 복잡한 최적화 코드를 한 줄도 작성하지 않고 실행 시점에 아래 플래그만 추가하면 된다.

bash
--model-impl transformers

이 설정 하나로 모델 배포에 드는 시간과 실제 추론 성능이라는 두 가지 목표를 동시에 달성할 수 있다. 정적 분석과 소스 코드 수준의 재작성이라는 공학적 접근이 수동 포팅의 공수를 완전히 대체하여 배포 효율을 높였다.

단순 어텐션 교체에서 전체 그래프 최적화로의 진화

엔지니어링 리소스는 곧 비용이다. 모델을 vLLM 같은 고성능 엔진에서 구동하기 위해 매번 모델 코드를 직접 이식하는 작업은 막대한 인적 비용과 시간을 소모한다. 기존의 transformers 백엔드는 추론의 가장 큰 병목 지점인 어텐션 연산에만 집중하는 전략을 취했다. 런타임에 vLLM이 제공하는 최적화된 어텐션 구현체를 플러그인 형태로 연결해 실행 효율을 높이는 방식이었다. 이는 단순한 교체만으로 어느 정도의 성능 향상을 가져왔지만 전체적인 최적화 관점에서는 부분적인 해결책에 불과했다.

어텐션 커널 교체만으로는 GPU 하드웨어의 잠재력을 완전히 끌어내기에 한계가 명확했다. GPU 간 병렬화 설정이나 컴파일 최적화, 퓨즈드 커널(fused kernels, 여러 연산을 하나의 GPU 커널로 통합해 메모리 접근을 줄이는 기술) 적용 같은 고수준의 하드웨어 가속은 여전히 수동 포팅의 영역이었다. 최상의 추론 성능을 확보하려는 개발자들은 결국 vLLM 네이티브 구현체를 직접 작성하는 고된 작업을 반복해야 했다. 수동 포팅은 모델이 업데이트될 때마다 동일한 최적화 과정을 다시 거쳐야 한다는 운영상의 부담을 안겼다.

최신 버전의 transformers 백엔드는 동적 레이어 퓨전(layer fusion, 여러 연산을 하나로 합쳐 계산 효율을 높이는 기술)을 도입해 이 문제를 해결했다. 런타임에 추론 전용 레이어 퓨전을 자동으로 적용함으로써 수동으로 작성한 최적화 코드와 대등한 수준의 하드웨어 최적화 성능을 구현한다. 호환 가능한 아키텍처라면 개발자가 직접 커널을 설계하거나 메모리 접근 경로를 수정하지 않아도 최적의 성능을 낼 수 있다. 이는 최적화의 주체를 사람에서 시스템으로 옮긴 결과다.

이러한 성능 달성은 `torch.fx`와 `ast`를 활용한 그래프 최적화 덕분이다. `torch.fx`를 통해 모델 그래프의 정적 분석(코드 실행 전 구조를 파악하는 것)을 수행하여 최적화가 가능한 특정 연산 패턴을 탐색한다. 이후 `ast`(추상 구문 트리, 소스 코드를 트리 구조로 표현한 것)를 이용해 소스 코드를 직접 조작하고 연산을 즉석에서 재작성하는 과정을 거친다. 결과적으로 사용자는 `--model-impl transformers` 플래그 하나만 추가하는 것으로 별도의 최적화 코드 작성 없이 네이티브 vLLM의 추론 속도를 그대로 확보하게 된다.

모델 포팅 비용 제로화가 가져올 배포 효율성

vLLM 같은 고성능 엔진에서 모델을 구동하려면 모델 코드를 엔진 규격에 맞춰 다시 짜는 포팅 과정에 상당한 시간이 소요되었다. transformers 라이브러리는 450개 이상의 아키텍처를 일관된 API로 지원하며 머신러닝 모델링의 표준 레퍼런스 역할을 수행한다. 기여자들이 이 라이브러리에서 모델 구조를 학습하고 이를 vLLM, SGLang, MLX, llama.cpp 등 타 프레임워크로 이식하는 과정이 생태계의 일반적인 경로였다. 모델 설계라는 본질적인 작업보다 추론 엔진의 특성에 맞게 코드를 수정하고 최적화하는 반복적인 구현 작업에 더 많은 공수가 투입되는 비효율이 존재했다.

이제 최적화 코드를 단 한 줄도 작성하지 않고 vLLM 네이티브 구현체와 대등한 추론 속도를 확보할 수 있다. 이는 transformers 백엔드가 모델의 연산 그래프를 분석해 최적의 경로를 자동으로 찾아내기 때문이다. 수동으로 작성한 네이티브 구현체와 transformers 백엔드의 성능 차이를 검증하는 실행 파일은 아래 주소에서 제공한다.

benchmark.sh

개발자는 더 이상 하드웨어의 최대 성능을 끌어내기 위해 vLLM 전용 구현체를 따로 작성하는 수고를 들일 필요가 없다. 모델 배포 속도와 추론 성능이라는 상충하는 두 가지 목표를 동시에 달성하며 모델의 시장 출시 주기를 획기적으로 단축할 수 있다.

성능 최적화의 핵심은 `torch.fx`를 통한 정적 분석과 `ast`를 이용한 소스 코드 수준의 레이어 퓨전이다. torch.fx는 코드를 실제로 실행하지 않고 모델의 연산 그래프 구조를 파악하는 정적 분석 도구이며, ast는 소스 코드를 트리 구조로 표현해 조작하는 추상 구문 트리다. 이 두 기술을 결합해 런타임에 여러 연산을 하나로 합쳐 계산 효율을 높이는 레이어 퓨전을 동적으로 적용한다. 기존에는 GPU 간 병렬화나 퓨즈드 커널처럼 메모리 접근을 줄이는 하드웨어 가속 최적화를 위해 수동 포팅이 필수적이었으나, 이제는 자동화된 기법으로 동일한 수준의 하드웨어 효율을 구현한다.

실제 배포 환경에서는 `--model-impl transformers` 플래그 하나만 추가하면 모든 최적화가 적용된다.

bash
--model-impl transformers

이 설정은 기존의 병렬화 옵션과 그대로 결합되므로 서빙 인프라의 설정 자체를 변경할 필요가 없다. 다만 선형 어텐션 모델은 현재 지원 대상에서 제외되며, 허브 저장소에 코드가 포함된 커스텀 모델은 규격을 준수하지 않았을 때 작동하지 않을 가능성이 있다. 모델 개발자는 이제 하위 레벨의 엔진 최적화라는 기술적 부채에서 벗어나 모델 아키텍처 설계라는 본연의 과제에 모든 역량을 집중할 수 있는 환경을 갖게 되었다.

고성능 추론 엔진을 위해 모델 코드를 일일이 옮기던 수동 포팅의 번거로움은 이제 기술적 부채가 되었다. torch.fx를 통한 정적 분석과 ast 기반의 소스 코드 수준 레이어 퓨전이 결합하며, 별도의 최적화 구현 없이도 네이티브 수준의 추론 속도를 달성했기 때문이다. 이는 엔지니어가 하위 레벨의 최적화 작업 대신 모델 아키텍처 설계라는 본연의 과제에 집중할 수 있는 환경을 의미한다. 이제 `--model-impl transformers` 플래그 하나로 배포 속도와 성능을 동시에 확보하며 최적의 추론 환경을 구축할 수 있다.