fix(embedder): avoid vLLM exact-max_model_len hang; tune batch_size default - #495
Conversation
…efault vLLM pooling models (e.g. Qwen3-Embedding) hang indefinitely on an embedding request whose input is exactly max_model_len tokens long (vllm-project/vllm#29496, closed "not planned"). We send truncate_prompt_tokens = max_model_len, so any chunk >= max_model_len is truncated straight onto that boundary — wedging that one batch forever while the rest of the document and other files keep embedding fine. Truncate to max_model_len - 1 (floored at 1) to stay off the boundary. Also lower the default embedder batch_size 64 -> 32 across config.yaml, EmbedderConfig, and the VLLMEmbedder constructor: smaller batches shrink each request and the blast radius of any single slow/stuck batch, and align the legacy embedder default with the named-endpoint ModelEndpointConfig default (also 32). timeout (120s) and embed_concurrency (4) are unchanged. Updates the truncate test (8192 -> 8191) and adds a floor-at-1 case.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthrough
ChangesEmbedder batch size and truncation fixes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Problem
When indexing certain files, embedding completes every batch except one, which hangs indefinitely — systematically reproducible for the same file, while other files index fine in parallel (the server keeps serving). So it's content-related, not load or client.
Root cause: vLLM issue #29496 — Qwen3-Embedding (and other vLLM pooling models) hang forever on an embedding request whose input is exactly
max_model_lentokens long. Reducing the input by a single token fixes it; the issue was closed "not planned".Our embedder sent
truncate_prompt_tokens = max_model_len, so any chunk ≥max_model_lenwas truncated straight onto that hang boundary, wedging that one batch while the rest of the document (and other files) embedded normally.Changes
Truncate one token below the boundary.
_embed_batchnow sendstruncate_prompt_tokens = max(1, max_model_len - 1)so a truncated chunk lands atmax_model_len - 1, never on the hang boundary. Applies to everyVLLMEmbedder(default and named-endpoint paths). Floored at 1 for safety.Lower the default embedder
batch_size64 → 32 across the three sources of truth (conf/config.yaml,EmbedderConfig,VLLMEmbedderconstructor). Smaller batches shrink each request and the blast radius of any single slow/stuck batch, and align the legacy embedder default with the named-endpointModelEndpointConfigdefault (also 32).timeout(120s) andembed_concurrency(4) are unchanged — already reasonable; all three remain overridable viaEMBEDDER_TIMEOUT/EMBEDDER_BATCH_SIZE/EMBEDDER_CONCURRENCY.Tests
test_truncate_prompt_tokens_is_one_below_max_model_len(8192 → 8191) and a newtest_truncate_prompt_tokens_floors_at_one.Summary by CodeRabbit
Bug Fixes
Chores