Generic vLLM wrapper for LLM-based ASR models. Automatically detects model architecture, extracts LLM weights, loads audio components in PyTorch, and uses vLLM for generation. Works for: FunASRNano, LLMASR, GLMASR, and any model with audio_encoder + audio_adaptor + LLM architecture
| 179 | |
| 180 | |
| 181 | class AutoModelVLLM: |
| 182 | """Generic vLLM wrapper for LLM-based ASR models. |
| 183 | |
| 184 | Automatically detects model architecture, extracts LLM weights, |
| 185 | loads audio components in PyTorch, and uses vLLM for generation. |
| 186 | |
| 187 | Works for: FunASRNano, LLMASR, GLMASR, and any model with |
| 188 | audio_encoder + audio_adaptor + LLM architecture. |
| 189 | |
| 190 | Args: |
| 191 | model: Model name (hub) or local directory path. |
| 192 | hub: "ms" (ModelScope) or "hf" (HuggingFace). |
| 193 | device: Device for audio encoder/adaptor. |
| 194 | dtype: Compute dtype ("bf16", "fp16", "fp32"). |
| 195 | tensor_parallel_size: GPUs for vLLM tensor parallelism. |
| 196 | gpu_memory_utilization: GPU memory fraction for vLLM. |
| 197 | max_model_len: Maximum sequence length. |
| 198 | |
| 199 | Example: |
| 200 | >>> model = AutoModelVLLM(model="FunAudioLLM/Fun-ASR-Nano-2512") |
| 201 | >>> results = model.generate(["audio.wav"], language="中文") |
| 202 | """ |
| 203 | |
| 204 | def __init__( |
| 205 | self, |
| 206 | model: str, |
| 207 | hub: str = "ms", |
| 208 | device: str = "cuda:0", |
| 209 | dtype: str = "bf16", |
| 210 | tensor_parallel_size: int = 1, |
| 211 | gpu_memory_utilization: float = 0.8, |
| 212 | max_model_len: int = 4096, |
| 213 | enforce_eager: bool = False, |
| 214 | **kwargs, |
| 215 | ): |
| 216 | # Resolve model directory |
| 217 | if os.path.isdir(model): |
| 218 | self.model_dir = model |
| 219 | else: |
| 220 | if hub in ("ms", "modelscope"): |
| 221 | from modelscope.hub.snapshot_download import snapshot_download |
| 222 | self.model_dir = snapshot_download(model, revision=kwargs.get("revision", "master")) |
| 223 | elif hub in ("hf", "huggingface"): |
| 224 | from huggingface_hub import snapshot_download |
| 225 | self.model_dir = snapshot_download(model) |
| 226 | else: |
| 227 | raise ValueError(f"Unsupported hub: {hub}") |
| 228 | |
| 229 | # Check model type |
| 230 | from omegaconf import OmegaConf |
| 231 | config = OmegaConf.load(os.path.join(self.model_dir, "config.yaml")) |
| 232 | self.model_type = config.get("model", "unknown") |
| 233 | check_vllm_applicable(self.model_type) |
| 234 | |
| 235 | self.device = device |
| 236 | self.dtype = dtype |
| 237 | self.torch_dtype = dtype_map.get(dtype, torch.bfloat16) |
| 238 |
no outgoing calls
no test coverage detected
searching dependent graphs…