지원되는 모델
지원되는 모델 (Supported Models)
vLLM은 정말 많은 모델을 지원해요. 생성형(generative) 모델과 pooling 모델을 다양한 태스크에서 쓸 수 있고, 각 태스크마다 vLLM에 구현된 모델 아키텍처 목록이 정리돼 있어요. 이 페이지에서는 어떤 모델이 어떻게 지원되는지, 그리고 목록에 없는 새 모델은 어떻게 쓰는지까지 차근차근 알아볼게요.
vLLM은 다양한 태스크에 걸쳐 생성형 모델과 pooling 모델을 지원해요. 각 태스크마다 vLLM에 구현된 모델 아키텍처를 나열하고, 각 아키텍처를 쓰는 인기 모델도 함께 소개해요.
모델 구현 (Model Implementation)
vLLM (네이티브 구현)
vLLM이 모델을 네이티브로 지원한다면 그 구현은 vllm/model_executor/models에서 찾을 수 있어요. 이 모델들이 지원 텍스트 모델 목록과 지원 멀티모달 모델 목록에 나오는 것들이에요.
Transformers (Transformers 모델링 백엔드)
vLLM은 Transformers에 있는 모델 구현도 지원해요. 이 기능을 "Transformers modeling backend" 라고 불러요. Transformers 모델링 백엔드로 로드한 모델의 성능은 전용 vLLM 모델 구현과 동일해야 해요.
현재 Transformers 모델링 백엔드는 다음을 지원해요.
- 양식(modality): 임베딩 모델, 언어 모델, 비전-언어 모델*, 오디오-언어 모델
- 아키텍처: encoder-only, decoder-only, mixture-of-experts
- 어텐션 타입: full attention 및/또는 sliding attention
*비전-언어 모델은 현재 이미지 입력만 받아요. 비디오 입력 지원은 향후 릴리스에서 추가될 예정이에요.
Transformers 모델 구현이 커스텀 모델 작성의 모든 단계를 따른다면, Transformers 모델링 백엔드와 함께 쓸 때 다음 vLLM 기능과 호환돼요.
- 호환성 매트릭스에 나열된 모든 기능
- 다음 vLLM 병렬화 방식의 임의 조합:
- Data parallel
- Tensor parallel
- Expert parallel
- Pipeline parallel
모델링 백엔드가 Transformers인지 확인하는 건 아주 간단해요.
from vllm import LLM
llm = LLM(model=...) # Name or path of your model
llm.apply_model(lambda model: print(type(model)))
출력된 타입이 Transformers...로 시작하면 Transformers 모델 구현을 쓰고 있는 거예요!
모델에 vLLM 구현이 있는데 굳이 Transformers 구현을 쓰고 싶다면, 오프라인 추론에서 model_impl="transformers"를, 온라인 서빙에서 --model-impl transformers를 설정하면 돼요.
참고: 비전-언어 모델의 경우
dtype="auto"로 로드하면, config에dtype이 있을 때 vLLM은 전체 모델을 그 dtype으로 로드해요. 반면 네이티브 Transformers는 모델의 각 백본dtype속성을 존중해요. 그래서 성능에 약간의 차이가 있을 수 있어요.
커스텀 모델 (Custom models)
모델이 vLLM에도, Transformers에도 네이티브로 지원되지 않아도 vLLM에서 쓸 수 있어요!
vLLM의 Transformers 모델링 백엔드와 호환되려면 모델이 다음 조건을 만족해야 해요.
- Transformers 호환 커스텀 모델이어야 해요 (Transformers - Customizing models 참고):
- 모델 디렉토리가 올바른 구조여야 해요 (예:
config.json가 존재). config.json에auto_map.AutoModel이 포함돼야 해요.
- 모델 디렉토리가 올바른 구조여야 해요 (예:
- vLLM용 Transformers 모델링 백엔드와 호환돼야 해요 (커스텀 모델 작성 참고):
- 커스터마이징은 base model에서 해야 해요 (예:
MyModelForCausalLM이 아니라MyModel에서).
- 커스터마이징은 base model에서 해야 해요 (예:
호환되는 모델이:
- Hugging Face Model Hub에 있다면, 오프라인 추론에서
trust_remote_code=True, 온라인 서빙에서--trust-remote-code를 설정하면 돼요. - 로컬 디렉토리에 있다면, 오프라인 추론에서
model=<MODEL_DIR>로, 온라인 서빙에서vllm serve <MODEL_DIR>로 디렉토리 경로를 넘기면 돼요.
즉, vLLM용 Transformers 모델링 백엔드를 쓰면 Transformers나 vLLM에서 공식 지원되기 전의 새 모델도 쓸 수 있어요!
커스텀 모델 작성 (Writing custom models)
이번에는 Transformers 호환 커스텀 모델을 vLLM용 Transformers 모델링 백엔드에 맞게 수정하는 방법을 살펴볼게요. (Transformers 호환 커스텀 모델은 이미 만들었다고 가정해요.)
모델을 Transformers 모델링 백엔드와 호환되게 만들려면:
MyAttention이ALL_ATTENTION_FUNCTIONS를 사용해 어텐션을 호출해야 해요.- 정확히 한 번만 호출해야 해요. vLLM은
MyAttention모듈 하나당Attention레이어 하나를 붙여요. MyAttention은 고유한layer_idx를 가져야 해요. vLLM은 이 인덱스로 KV cache를 구분해요.- 스케일이
head_size**-0.5가 아니라면 인터페이스에scaling=을 전달해요. vLLM은 어텐션 인터페이스 호출에서 이를 읽어요.
- 정확히 한 번만 호출해야 해요. vLLM은
- 모델이 encoder-only라면:
MyAttention에is_causal = False를 추가해요.
- 모델이 mixture-of-experts(MoE)라면:
- sparse MoE 블록에
experts라는 속성이 있어야 해요. experts의 클래스(MyExperts)는nn.ModuleList에서 상속받거나(naive), 모든 3Dnn.Parameters를 포함해야 해요(packed).MyExperts.forward는hidden_states,top_k_index,top_k_weights를 받아야 해요.
- sparse MoE 블록에
참고:
MyModel은 더 이상_supports_attention_backend = True가 필요 없고,MyModel에서MyAttention까지 모든 모듈에kwargs를 전달할 필요도 없어요. vLLM은MyAttention자체를 통해 어텐션 레이어에 도달하므로,MyAttention이 인터페이스를 통해 디스패치하기만 하면 돼요.
# modeling_my_model.py
from transformers import PreTrainedModel
from torch import nn
class MyAttention(nn.Module):
is_causal = False # Only do this for encoder-only models
def __init__(self, config, layer_idx):
...
self.config = config
self.layer_idx = layer_idx
self.scaling = self.head_dim**-0.5
...
def forward(self, hidden_states, **kwargs):
...
attention_interface = ALL_ATTENTION_FUNCTIONS.get_interface(
self.config._attn_implementation, eager_attention_forward
)
attn_output, attn_weights = attention_interface(
self,
query_states,
key_states,
value_states,
scaling=self.scaling,
**kwargs,
)
...
# Only do this for mixture-of-experts models
class MyExperts(nn.ModuleList):
def forward(self, hidden_states, top_k_index, top_k_weights):
...
# Only do this for mixture-of-experts models
class MySparseMoEBlock(nn.Module):
def __init__(self, config):
...
self.experts = MyExperts(config)
...
def forward(self, hidden_states: torch.Tensor):
...
hidden_states = self.experts(hidden_states, top_k_index, top_k_weights)
...
class MyModel(PreTrainedModel):
...
이 모델이 로드될 때 뒤에서 일어나는 일은 이래요.
- config가 로드돼요.
MyModelPython 클래스가 config의auto_map에서 로드되고, 모델의_can_set_attn_implementation()을 확인해요.MyModel이 vllm/model_executor/models/transformers의 Transformers 모델링 백엔드 클래스 하나로 로드돼서self.config._attn_implementation = "vllm"으로 설정돼요. 그래서 vLLM의 어텐션 레이어가 사용돼요.
그게 다예요!
모델이 vLLM의 tensor parallel 및/또는 pipeline parallel과 호환되게 하려면 config 클래스에 base_model_tp_plan 및/또는 base_model_pp_plan을 추가해야 해요.
# configuration_my_model.py
from transformers import PretrainedConfig
class MyConfig(PretrainedConfig):
base_model_tp_plan = {
"layers.*.self_attn.k_proj": "colwise",
"layers.*.self_attn.v_proj": "colwise",
"layers.*.self_attn.o_proj": "rowwise",
"layers.*.mlp.gate_proj": "colwise",
"layers.*.mlp.up_proj": "colwise",
"layers.*.mlp.down_proj": "rowwise",
}
base_model_pp_plan = {
"embed_tokens": (["input_ids"], ["inputs_embeds"]),
"layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
"norm": (["hidden_states"], ["hidden_states"]),
}
base_model_tp_plan은 완전한 레이어 이름 패턴을 tensor parallel 스타일로 매핑하는dict예요 (현재는"colwise"와"rowwise"만 지원).- vLLM은 퓨전이 가능하면 표준 어텐션(
q/k/v/o_proj)과 gated-MLP/experts(gate/up/down_proj)의 tensor parallel 스타일을 추론하므로, 이들은 나열하지 않아도 될 수 있어요.base_model_tp_plan은 이런 패턴을 따르지 않는 레이어에만 _필수_예요. 퓨전되지도 plan에 없지도 않은 linear는 복제(replicate)돼요.
- vLLM은 퓨전이 가능하면 표준 어텐션(
base_model_pp_plan은 직접 자식 레이어 이름을list들의list인str의tuple로 매핑하는dict예요.- 모든 파이프라인 스테이지에 없는 레이어에 대해서만 하면 돼요.
- vLLM은
nn.ModuleList가 하나만 있을 거라고 가정하고, 이를 파이프라인 스테이지에 걸쳐 분산해요.
참고 (확인 필요): vLLM 네이티브로 지원되지 않는 비전-언어 모델을
dtype="auto"로 로드할 때의 동작 차이는 위의 주의사항을 참고하세요.