|
| 1 | +// Ported from: vllm/v1/engine/input_processor.py @ e24d1b24 |
| 2 | +// (InputProcessor.__init__ + process_inputs, the T0 text path). |
| 3 | +// |
| 4 | +// Scope (M1.8 Task 2): turn a text prompt + SamplingParams into an |
| 5 | +// EngineCoreRequest the EngineCore (Task 1) can schedule. This is the T0 slice of |
| 6 | +// upstream InputProcessor.process_inputs (input_processor.py:242-385): |
| 7 | +// _validate_params -> RUN SamplingParams::PostInit()/Verify() (see below) |
| 8 | +// preprocess/tokenize -> tokenizer.Encode(prompt) -> prompt_token_ids |
| 9 | +// sampling_params.clone() (implicit: params passed by value) |
| 10 | +// default max_tokens = model_config.max_model_len - len(prompt) when unset |
| 11 | +// update_from_generation_config(generation_config, eos_token_id) (:323) |
| 12 | +// update_from_tokenizer(tokenizer) (:328) |
| 13 | +// -> EngineCoreRequest(request_id, prompt_token_ids, sampling_params, ...) |
| 14 | +// |
| 15 | +// THE M1.1 CARRY THIS CLOSES: our SamplingParams (M1.1) deferred __post_init__ |
| 16 | +// to "the constructing unit — M1.8". The InputProcessor IS that unit: |
| 17 | +// ValidateParams runs PostInit() (which normalizes in place AND runs Verify()), |
| 18 | +// mirroring upstream, where __post_init__ ran at SamplingParams construction and |
| 19 | +// process_inputs then calls params.verify(model_config, ...). |
| 20 | +// |
| 21 | +// DEVIATIONS vs the pinned API (recorded, use OUR names): |
| 22 | +// - __init__ takes VllmConfig (from which it pulls model_config, |
| 23 | +// generation_config_fields and a renderer holding the tokenizer). We hold a |
| 24 | +// tokenizer + HfConfig reference directly (the T0 deps), deriving |
| 25 | +// max_model_len from HfConfig.max_position_embeddings and the primary eos + |
| 26 | +// secondary eos ids from HfConfig.raw["eos_token_id"] (int OR list) with a |
| 27 | +// Tokenizer::EosId() fallback. HfConfig has no max_model_len override |
| 28 | +// (rope-scaling etc.), so max_position_embeddings stands in for it at T0. |
| 29 | +// - process_inputs signature reordered to (request_id, prompt, params, |
| 30 | +// arrival_time): only the text prompt + SamplingParams path is kept. |
| 31 | +// - update_from_generation_config: our SamplingParams dropped the |
| 32 | +// _all_stop_token_ids field (M1.1 — the detokenizer computes its own stop |
| 33 | +// buffer), so the only observable T0 effect is setting eos_token_id and |
| 34 | +// merging the SECONDARY eos ids into stop_token_ids (both gated on |
| 35 | +// ignore_eos), matching sampling_params.py:627-655. |
| 36 | +// - update_from_tokenizer is a no-op stub: upstream only processes bad_words |
| 37 | +// there (sampling_params.py:657), and bad_words is a deferred SamplingParams |
| 38 | +// field (M1.1). |
| 39 | +// |
| 40 | +// DEFERRED (marked; matches upstream so re-adding is mechanical): dict/EngineInput |
| 41 | +// prompts, prompt_embeds, encoder/decoder split, multimodal (mm_features), |
| 42 | +// pooling (PoolingParams), LoRA, data_parallel_rank validation, request-id |
| 43 | +// randomization (assign_request_id), _validate_model_inputs (prompt-length / |
| 44 | +// out-of-vocab checks), current_platform.validate_request, trace_headers, |
| 45 | +// priority, resumable. |
| 46 | +#pragma once |
| 47 | + |
| 48 | +#include <cstdint> |
| 49 | +#include <optional> |
| 50 | +#include <string> |
| 51 | +#include <vector> |
| 52 | + |
| 53 | +#include "vllm/sampling_params.h" |
| 54 | +#include "vllm/transformers_utils/hf_config.h" |
| 55 | +#include "vllm/v1/engine/types.h" |
| 56 | + |
| 57 | +namespace vllm::tok { |
| 58 | +class Tokenizer; // vllm/tokenizer/tokenizer.h |
| 59 | +} |
| 60 | + |
| 61 | +namespace vllm::v1 { |
| 62 | + |
| 63 | +class InputProcessor { |
| 64 | + public: |
| 65 | + // __init__ (T0 deps): the tokenizer + HfConfig the processor reads. Both must |
| 66 | + // outlive the InputProcessor. Derives max_model_len + eos ids up front. |
| 67 | + InputProcessor(const tok::Tokenizer& tokenizer, const HfConfig& config); |
| 68 | + |
| 69 | + // process_inputs (text path): validate + tokenize + build the request. |
| 70 | + // `params` is taken BY VALUE (upstream clones it); PostInit()/eos-wiring |
| 71 | + // mutate the local copy, never the caller's. Throws std::runtime_error via |
| 72 | + // SamplingParams::Verify() on invalid params. arrival_time defaults to the |
| 73 | + // wall clock (upstream time.time()). |
| 74 | + EngineCoreRequest process_inputs( |
| 75 | + const std::string& request_id, const std::string& prompt, |
| 76 | + SamplingParams params, |
| 77 | + std::optional<double> arrival_time = std::nullopt) const; |
| 78 | + |
| 79 | + private: |
| 80 | + // _validate_params: runs SamplingParams::PostInit() (normalize + Verify) — |
| 81 | + // this closes the M1.1 deferred-__post_init__ carry. |
| 82 | + void ValidateParams(SamplingParams& params) const; |
| 83 | + // update_from_generation_config (T0 subset: eos_token_id + secondary stop ids). |
| 84 | + void UpdateFromGenerationConfig(SamplingParams& params) const; |
| 85 | + // update_from_tokenizer (T0 no-op: bad_words is deferred). |
| 86 | + void UpdateFromTokenizer(SamplingParams& params) const; |
| 87 | + |
| 88 | + const tok::Tokenizer& tokenizer_; |
| 89 | + const HfConfig& config_; |
| 90 | + // model_config.max_model_len (T0: HfConfig.max_position_embeddings). |
| 91 | + int64_t max_model_len_ = 0; |
| 92 | + // The primary eos id (renderer.get_eos_token_id()): the eos_ids list head, or |
| 93 | + // the tokenizer's eos, or unset. |
| 94 | + std::optional<int32_t> eos_token_id_; |
| 95 | + // generation_config["eos_token_id"] as a list (int is a 1-element list). |
| 96 | + std::vector<int32_t> generation_config_eos_ids_; |
| 97 | +}; |
| 98 | + |
| 99 | +} // namespace vllm::v1 |
0 commit comments