Log fully resolved pooling config at startup (#48030)

Signed-off-by: Taneem Ibrahim <taneem.ibrahim@gmail.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>

Taneem Ibrahim committed Jul 14, 2026 at 18:00 UTC 9182e8697133e95f6e4ed236628a344b12e1c702
3 files changed +78 -2
vllm/config/model.py
+13 -1
@@ -20,7 +20,7 @@ from vllm.config.multimodal import (
20 MMTensorIPC,
21 MultiModalConfig,
22 )
23 -from vllm.config.pooler import PoolerConfig
23 +from vllm.config.pooler import POOLER_CONFIG_LOG_FIELDS, PoolerConfig
24 from vllm.config.quantization import QuantizationConfigArgs
25 from vllm.config.scheduler import RunnerType
26 from vllm.config.utils import config, getattr_iter
@@ -640,6 +640,13 @@ class ModelConfig:
640 if self.runner_type == "pooling":
641 if self.pooler_config is None:
642 self.pooler_config = PoolerConfig()
643 + pooler_config_sources: dict[str, str] = {}
644 + else:
645 + pooler_config_sources = {
646 + k: "user"
647 + for k in POOLER_CONFIG_LOG_FIELDS
648 + if getattr(self.pooler_config, k) is not None
649 + }
650
651 base_config = get_pooling_config(self.model, self.revision)
652 if base_config is not None:
@@ -647,13 +654,18 @@ class ModelConfig:
654 for k, v in base_config.items():
655 if getattr(self.pooler_config, k) is None:
656 setattr(self.pooler_config, k, v)
657 + pooler_config_sources[k] = "sentence_transformers"
658
659 default_seq_pooling_type = self._model_info.default_seq_pooling_type
660 if self.pooler_config.seq_pooling_type is None:
661 self.pooler_config.seq_pooling_type = default_seq_pooling_type
662 + pooler_config_sources["seq_pooling_type"] = "model_default"
663 default_tok_pooling_type = self._model_info.default_tok_pooling_type
664 if self.pooler_config.tok_pooling_type is None:
665 self.pooler_config.tok_pooling_type = default_tok_pooling_type
666 + pooler_config_sources["tok_pooling_type"] = "model_default"
667 + pooler_config_sources.setdefault("use_activation", "pooler_default")
668 + self._pooler_config_sources = pooler_config_sources
669
670 self.dtype: torch.dtype = _get_and_verify_dtype(
671 self.model,
vllm/config/pooler.py
+6
@@ -16,6 +16,12 @@ SEQ_POOLING_TYPES: tuple[SequencePoolingType, ...] = get_args(SequencePoolingTyp
16 TokenPoolingType = Literal["ALL", "STEP"]
17 TOK_POOLING_TYPES: tuple[TokenPoolingType, ...] = get_args(TokenPoolingType)
18
19 +POOLER_CONFIG_LOG_FIELDS = (
20 + "seq_pooling_type",
21 + "tok_pooling_type",
22 + "use_activation",
23 +)
24 +
25
26 @config
27 class PoolerConfig:
vllm/v1/engine/core.py
+59 -1
@@ -22,6 +22,7 @@ import zmq
22
23 import vllm.envs as envs
24 from vllm.config import ParallelConfig, VllmConfig
25 +from vllm.config.pooler import POOLER_CONFIG_LOG_FIELDS
26 from vllm.distributed import (
27 cleanup_dist_env_and_memory,
28 stateless_destroy_torch_distributed_process_group,
@@ -121,6 +122,7 @@ class EngineCore:
122
123 # Setup Model.
124 self.model_executor = executor_class(vllm_config)
125 + self._pooler_config_logged = False
126 if executor_fail_callback is not None:
127 self.model_executor.register_failure_callback(executor_fail_callback)
128
@@ -348,7 +350,63 @@ class EngineCore:
350 return scheduler_kv_cache_config
351
352 def get_supported_tasks(self) -> tuple[SupportedTask, ...]:
351 - return self.model_executor.supported_tasks
353 + supported_tasks = self.model_executor.supported_tasks
354 + self._log_pooler_config(supported_tasks)
355 + return supported_tasks
356 +
357 + def _log_pooler_config(self, supported_tasks: tuple[SupportedTask, ...]) -> None:
358 + if self._pooler_config_logged:
359 + return
360 +
361 + model_config = self.vllm_config.model_config
362 + pooler_config = model_config.pooler_config
363 + if (
364 + self.vllm_config.parallel_config.data_parallel_rank_local
365 + or model_config.runner_type != "pooling"
366 + or pooler_config is None
367 + ):
368 + return
369 +
370 + supported_pooling_tasks = tuple(
371 + sorted(set(supported_tasks) & set(POOLING_TASKS))
372 + )
373 + if not supported_pooling_tasks:
374 + return
375 +
376 + self._pooler_config_logged = True
377 + task_set = set(supported_pooling_tasks)
378 + use_activation = pooler_config.use_activation
379 + if use_activation is None:
380 + use_activation = True
381 + sources = getattr(model_config, "_pooler_config_sources", {})
382 + pooling_type_field = (
383 + "seq_pooling_type"
384 + if task_set & {"embed", "classify"}
385 + else "tok_pooling_type"
386 + )
387 +
388 + def log_field(name: str, field: str) -> str:
389 + value = (
390 + use_activation
391 + if field == "use_activation"
392 + else getattr(pooler_config, field)
393 + )
394 + source = sources.get(field, "unknown")
395 + return f"{name}={value}(source={source})"
396 +
397 + log_items = [("pooling_type", pooling_type_field)]
398 + log_items.extend(
399 + (field, field)
400 + for field in POOLER_CONFIG_LOG_FIELDS
401 + if field != pooling_type_field
402 + )
403 + config_fields = ", ".join(log_field(name, field) for name, field in log_items)
404 +
405 + logger.info_once(
406 + "Resolved pooling config: %s, supported_tasks=%s",
407 + config_fields,
408 + supported_pooling_tasks,
409 + )
410
411 def get_kv_cache_group_metadata(self) -> list[dict[str, int | str | None]]:
412 """Return msgspec-serializable metadata for scheduler KV cache groups."""