Visual Token Pruner#
-
class VisualTokenPruner#
Abstract prefill-time visual-token pruner (batch 1).
The non-virtual pruneForPrefill() owns everything algorithms must not diverge on: the enablement guards (minVisualTokens, target-is-a-reduction), modality partitioning, and the target computation. Subclasses implement prune() — with full freedom over what “pruning” means (subset selection, token merging, per-image quotas, …) — and typically finish by calling compactToKeepList(), which owns the invariant-laden buffer compaction: all text tokens are always kept; kept tokens retain their original absolute RoPE positions; decode continues at the position after the unpruned sequence (matching the HF DART reference).
Instances are created through createVisualTokenPruner() and reused across requests, so per-request device work buffers should be preallocated in the constructor. The caller is responsible for the runtime gates (fresh KV cache, mRoPE engine, no spec decode, …) and for shrinking the context lengths to the returned pruned length.
Subclassed by trt_edgellm::rt::DartPruner
Public Functions
-
virtual ~VisualTokenPruner() = default#
-
virtual char const *name() const noexcept = 0#
Algorithm name (matches the registry key).
- int32_t pruneForPrefill(
- std::vector<int32_t> const &hostTokenIds,
- PipelineIO &io,
- int32_t origLen,
- cudaStream_t stream
Prune the assembled prefill inputs for a batch-1 request.
May synchronize
stream(algorithm-dependent); on return the compaction kernels are enqueued onstreamand the PipelineIO tensors are reshaped to the pruned length.- Parameters:
hostTokenIds – The request’s expanded token ids (image placeholders already inserted); visual positions are
tokenId == imageTokenId.io – Pipeline buffers;
inputsEmbedsmust currently be [1, origLen, hiddenSize].origLen – The unpruned prefill length (== hostTokenIds.size()).
stream – CUDA stream all device work runs on.
- Returns:
The pruned length P (< origLen), or origLen when pruning is skipped (no/too-few visual tokens, or the target keep count is not a reduction).
-
inline VisualPrunerConfig const &config() const noexcept#
-
virtual ~VisualTokenPruner() = default#
-
struct VisualPrunerConfig#
Visual-token pruning configuration (runtime-side; nothing is required in the exported engine config — the prune operates on runtime buffers only).
Public Members
-
bool enabled = {false}#
-
std::string algorithm = {"dart"}#
Pruning algorithm name, resolved through the pruner registry. Built-in: “dart” (default, duplication-aware; paper: “Stop Looking for Important Tokens
in Multimodal Language Models: Duplication Matters More”).
-
float reductionRatio = {0.25F}#
Fraction of visual tokens to remove (0.25 = keep 75%).
-
int32_t minVisualTokens = {16}#
Skip pruning when the request has fewer visual tokens than this (accuracy and break-even guard: tiny images gain nothing from pruning).
-
int32_t pivotImageTokens = {4}#
-
int32_t pivotTextTokens = {4}#
-
bool enabled = {false}#
-
struct ImageSpan#
One contiguous run of visual tokens (one image, or one video-frame block) with its per-image retention quota. Pruning within each span independently — rather than over one global candidate pool — guarantees every image keeps its proportional share of tokens (at least one), so a low-information image can never be starved by the others.
-
struct PruneRequest#
Guard-checked, modality-partitioned view of one batch-1 prefill request, prepared by VisualTokenPruner::pruneForPrefill and handed to the algorithm hook.
Public Members
-
Tensor const *embeds = {nullptr}#
Non-owning [origLen, hiddenSize] FP16 GPU view of the assembled input embeddings.
-
std::vector<int32_t> const *imagePositions = {nullptr}#
Positions of visual tokens in the sequence (ascending, non-empty).
-
std::vector<int32_t> const *textPositions = {nullptr}#
Positions of all non-visual tokens in the sequence (ascending).
-
std::vector<ImageSpan> const *imageSpans = {nullptr}#
Contiguous visual spans (one per image) with per-span retention quotas.
-
int32_t targetImageTokens = {0}#
Total number of visual tokens to retain — the sum of the per-span quotas (1 <= targetImageTokens < imagePositions->size()).
-
int32_t origLen = {0}#
Unpruned prefill length (== imagePositions->size() + textPositions->size()).
-
Tensor const *embeds = {nullptr}#
- void trt_edgellm::rt::registerVisualPruner(
- std::string const &name,
- VisualPrunerFactory factory
Register a pruning algorithm under
name(case-sensitive). The built-in “dart” is registered automatically; call this to plug in a custom algorithm before constructing the runtime. Re-registering a name replaces the previous factory.
- std::unique_ptr<VisualTokenPruner> trt_edgellm::rt::createVisualTokenPruner(
- VisualPrunerConfig const &config,
- LLMEngineConfig const &engineConfig
Instantiate the pruner named by
config.algorithm.- Throws:
std::runtime_error – if the name is not registered or the config is invalid.
- std::vector<std::string> trt_edgellm::rt::registeredVisualPrunerNames(
Names of all registered pruning algorithms (for CLI help / validation).