mstar.engine.resources#
The resource layer’s declaration surface.
Everything re-exported here is a declaration — a spec, a per-request config, a step, or the generic step envelope — and every module behind it is free of the managers and their kernels. So a model can import all of it in one line without dragging FlashInfer or Triton in behind it; the concrete resources are reached by their own paths.
Nothing inside the package may import from here: during this module’s own execution the package is only half-initialized. Import siblings by their submodule path instead.
- class mstar.engine.resources.AdmitFailedReason(message: str)[source]#
Bases:
object- Parameters:
message (str)
- class mstar.engine.resources.AdmitOutcome(ok, ready, reason)[source]#
Bases:
NamedTuple- Parameters:
ok (bool)
ready (bool)
reason (AdmitFailedReason | None)
- reason: AdmitFailedReason | None#
Alias for field number 2
- class mstar.engine.resources.AdmitRuntimeError(message)[source]#
Bases:
AdmitFailedReasonA resource cannot serve this request at all.
Terminal, unlike the two above: no eviction and no reload makes it go away, so the caller’s answer is to fail the request, not to retry it.
- Parameters:
message (str)
- class mstar.engine.resources.AllocationFailed(message: str, pages_short: int, label: str, request_id: str)[source]#
Bases:
AdmitFailedReason
- class mstar.engine.resources.AttentionConfig(kv_cache: str, backend: mstar.engine.resources.attn.config.AttnBackend = <AttnBackend.FLASHINFER: 'flashinfer'>, flashinfer_backend: str = 'auto')[source]#
Bases:
object- Parameters:
kv_cache (str)
backend (AttnBackend)
flashinfer_backend (str)
- backend: AttnBackend = 'flashinfer'#
- class mstar.engine.resources.AttentionSpec(resource_key: str, nodes: set[str], config: mstar.engine.resources.attn.config.AttentionConfig)[source]#
Bases:
NodeResourceSpec- Parameters:
resource_key (str)
config (AttentionConfig)
- apply_yaml_overrides(backend=None, flashinfer_backend=None)[source]#
Which kernel to run is the deployment’s call as much as the model’s — an image that cannot build FA3 pins FA2 here.
Cache geometry is not repeated here: it belongs to the KV resource this spec depends on, and is tuned under that resource’s own block.
- Parameters:
backend (str | AttnBackend | None)
flashinfer_backend (str | None)
- config: AttentionConfig#
- class mstar.engine.resources.AttentionStep(segments: tuple[mstar.engine.resources.step.Segment, ...] | None = None, causal: bool = True)[source]#
Bases:
ResourceStep
- class mstar.engine.resources.AttnBackend(*values)[source]#
Bases:
Enum- DENSE = 'dense'#
- FLASHINFER = 'flashinfer'#
- FLEX = 'flex'#
- XPU_PAGED = 'xpu_paged'#
- class mstar.engine.resources.BucketKey(graph_walk: str, bs: int, num_tokens: int, cg_key_info: Any | None = None)[source]#
Bases:
object
- class mstar.engine.resources.CGSlotSpec(bucket: 'BucketKey', slot: 'int', config: 'CudaGraphConfig | PiecewiseCudaGraphConfig', config_idx: 'int | None' = None)[source]#
Bases:
object- Parameters:
bucket (BucketKey)
slot (int)
config (CudaGraphConfig | PiecewiseCudaGraphConfig)
config_idx (int | None)
- property bs#
- config: CudaGraphConfig | PiecewiseCudaGraphConfig#
- property num_tokens#
- class mstar.engine.resources.CrossAttentionConfig(kv_cache, query_kv_cache=None, context_label='context', backend=AttnBackend.FLASHINFER, flashinfer_backend='auto')[source]#
Bases:
objectCross-attention against a context written once and never extended.
kv_cachenames the KV resource holding the encoder context;query_kv_cachenames the decoder’s KV resource, whose plan defines this step’s query packing. They may be the same resource when the context shares the decoder’s head config — the context then lives in it under its owncontext_label. They differ when it does not, which is the usual case (an encoder’s head count rarely matches the decoder’s).query_kv_cache=Nonecovers the query side having no KV cache at all (nothing is cached across steps on it): the packing then comes off the cross-attention step’s own segments, one qo entry per segment in declared order.- Parameters:
kv_cache (str)
query_kv_cache (str | None)
context_label (str)
backend (AttnBackend)
flashinfer_backend (str)
- backend: AttnBackend = 'flashinfer'#
- class mstar.engine.resources.CrossAttentionSpec(resource_key: str, nodes: set[str], config: mstar.engine.resources.attn.config.CrossAttentionConfig)[source]#
Bases:
NodeResourceSpec- Parameters:
resource_key (str)
config (CrossAttentionConfig)
- apply_yaml_overrides(backend=None, flashinfer_backend=None)[source]#
Which kernel to run against the context cache; see
AttentionSpec.- Parameters:
backend (str | AttnBackend | None)
flashinfer_backend (str | None)
- config: CrossAttentionConfig#
- class mstar.engine.resources.FullAdmitOutcome(outcome, failed_resource=None)[source]#
Bases:
NamedTupleWhat the runner answers with: one resource’s outcome, plus which resource gave it.
A resource doesn’t know the key it is registered under, so the runner — which does — names it on the way out. The caller needs it to scope an eviction to the resource that actually ran out.
- Parameters:
outcome (AdmitOutcome)
failed_resource (str | None)
- outcome: AdmitOutcome#
Alias for field number 0
- property reason: AdmitFailedReason | None#
- class mstar.engine.resources.KVConfig(*, num_layers, num_kv_heads, head_dim, num_qo_heads=None)[source]#
Bases:
ABCThe model geometry every KV storage strategy needs, and nothing else.
What a cache holds (layers, heads, head dim) is a checkpoint fact and lives here; how it is stored — paged or ringed, is storage policy and lives in a subclass.
KVSpecdispatches on which one it was handed.kw_onlyis load-bearing, not style:num_qo_headscarries a default here while both subclasses add required fields, which is an invalid positional dataclass field order.- abstractmethod apply_yaml_overrides(**kwargs)[source]#
Patch this deployment’s tunables; see
NodeResourceSpec.Abstract so each storage policy names exactly what it accepts and lets the rest raise — a paged key against a ring config is a typo, and the spec’s contract is that a typo is loud.
- Return type:
None
- shard(num_shards)[source]#
Narrow the head counts to one rank’s slice.
Idempotent because one KVConfig is shared by the KV resource and the attention resources planned against it, and each shards on construction.
num_shardsis the instance session size (tp * sp): Ulysses SP all-to-alls heads, so attention runs at head-degree tp*sp.- Parameters:
num_shards (int)
- Return type:
None
- class mstar.engine.resources.KVReqConfig(needed_labels: list[str] | None = None, needed_labels_per_node: dict[str, list[str]] = <factory>, needed_labels_per_node_walk: dict[tuple[str, str], list[str]] = <factory>, publish_labels_per_node_walk: dict[tuple[str, str], list[str]] | None = None, final_publish_labels_per_node_walk: dict[tuple[str, str], list[str]] | None = None, prefix_keys: dict[str, list[bytes]] | None = None, prefix_tail: dict[str, list[int]] | None = None, prefix_decode: dict[str, str] | None = None, prefix_cache: bool = True)[source]#
Bases:
ResourceReqConfig- Parameters:
- apply_conductor_config(prefix_keys=None, prefix_tail=None, prefix_decode=None, prefix_cache=None, **kwargs)[source]#
- class mstar.engine.resources.KVSpec(resource_key: str, nodes: set[str], config: mstar.engine.resources.kv.config.KVConfig)[source]#
Bases:
NodeResourceSpec
- class mstar.engine.resources.KVStep(segments: tuple[mstar.engine.resources.step.Segment, ...] | None = None, commit: bool = True, combined_labels: dict[tuple[str, ...], str] = <factory>, pre_forks: tuple[tuple[str, str], ...] = (), post_forks: tuple[tuple[str, str], ...] = (), retention: collections.abc.Mapping[tuple[str, str], mstar.engine.resources.kv.config.RetentionPolicy] = <factory>)[source]#
Bases:
ResourceStep- Parameters:
- class mstar.engine.resources.NodeResourceSpec(resource_key: str, nodes: set[str])[source]#
Bases:
ABC- apply_yaml_overrides(**kwargs)[source]#
Patch declared parameters from this resource’s YAML block.
The model declares shapes that suit the model; a deployment tunes what suits the box it runs on. The block is scoped to this spec’s
resource_key(seeapply_yaml_overridesbelow), so an unrecognized key here is a typo, not another resource’s setting — subclasses name exactly what they accept and let the rest raise.TODO: generalize. Matching YAML keys against the spec’s (and its config’s) dataclass fields would remove these per-resource implementations, at the cost of silently accepting anything named alike.
- depends_on()[source]#
Keys whose specs this one builds against; the engine resolves them into
EngineResourceInfo.dependencies.
- class mstar.engine.resources.PagedKVConfig(*, num_layers, num_kv_heads, head_dim, num_qo_heads=None, max_seq_len, max_num_pages=2048, page_size=128, layout=KVLayout.NHD, cpu_offload_pages=0, prefix_cache_salt='', prefix_cache=True)[source]#
Bases:
KVConfigFixed-size pages, appended to as a sequence grows. The default.
- Parameters:
- class mstar.engine.resources.PosScheme(*values)[source]#
Bases:
Enum- BLOCK = 'block'#
- SEQUENTIAL = 'sequential'#
- class mstar.engine.resources.PositionConfig(kv_cache: str, backend: mstar.engine.resources.position.config.PosBackend = <PosBackend.ROPE: 'rope'>, scheme: mstar.engine.resources.position.config.PosScheme = <PosScheme.SEQUENTIAL: 'sequential'>, block_step: int = 1, rotary_dim: int | None = None, interleave: bool = False, rope_scale: float = 1.0, rope_theta: float = 10000.0, rope_dtype: torch.dtype | None = None, low_freq_factor: float | None = None, high_freq_factor: float | None = None, old_context_len: int | None = None)[source]#
Bases:
object- Parameters:
- backend: PosBackend = 'rope'#
- class mstar.engine.resources.PositionSpec(resource_key: str, nodes: set[str], config: mstar.engine.resources.position.config.PositionConfig)[source]#
Bases:
NodeResourceSpec- Parameters:
resource_key (str)
config (PositionConfig)
- config: PositionConfig#
- class mstar.engine.resources.PositionStep(segments: tuple[mstar.engine.resources.step.Segment, ...] | None = None, pos_ids: 'dict[str, torch.Tensor] | torch.Tensor | None' = None, advance: tuple[int, ...] | None = None)[source]#
Bases:
ResourceStep- Parameters:
- class mstar.engine.resources.PublishedInfo[source]#
Bases:
ABC- abstractmethod clone()[source]#
Return independent publication metadata for deferred sending.
- Return type:
- abstractmethod update(other)[source]#
- Parameters:
other (PublishedInfo)
- Return type:
None
- class mstar.engine.resources.RaggedAttentionConfig(num_qo_heads, num_kv_heads, head_dim, sm_scale=None, max_segments_per_request=1, max_tokens_per_request=None, flashinfer_backend='auto', dtype=None)[source]#
Bases:
objectVarlen self-attention over segments packed into one forward, with no KV cache: the whole layout is this step’s, and nothing carries to the next.
Head counts are pre-sharding; the engine narrows them to the rank’s slice at build, as it does for a
KVConfig.- Parameters:
- class mstar.engine.resources.RaggedAttentionSpec(resource_key: str, nodes: set[str], config: mstar.engine.resources.attn.ragged.config.RaggedAttentionConfig)[source]#
Bases:
NodeResourceSpec- Parameters:
resource_key (str)
config (RaggedAttentionConfig)
- apply_yaml_overrides(flashinfer_backend=None, max_segments_per_request=None, max_tokens_per_request=None)[source]#
Which kernel to run is the deployment’s call as much as the model’s — an image that cannot build FA3 pins FA2 here.
The two ceilings are here rather than on the model because they size CUDA-graph buckets, which is a deployment’s memory/coverage trade.
- config: RaggedAttentionConfig#
- class mstar.engine.resources.RequestOffloading(message, label, request_id)[source]#
Bases:
AdmitFailedReasonThe request’s state is moving to host memory; retry once it is back.
Distinct from AllocationFailed because the answer is different: nothing needs evicting, the caller just re-drives the step once reload has run.
- class mstar.engine.resources.Resource[source]#
Bases:
ABC- admit(step, ctx)[source]#
Reserve space for the given step. In the case where requests in a batch must be executed sequentially, this may be called for all requests in a loop before the per-request plan -> forward -> commit cycle.
- Parameters:
step (ResourceStep)
ctx (StepContext)
- Return type:
- admit_retrieve(rid, node_name, graph_walk, published)[source]#
Takes the output of publish, possibly from another device, and kicks of a retrieval if needed (e.g., PD disaggregation KV transfer). Returns whether the retrieve has completed.
- Parameters:
rid (str)
node_name (str)
graph_walk (str)
published (PublishedInfo | None)
- Return type:
- apply_cached_prefix(rid, node_name, graph_walk, inputs, matched_len)[source]#
Take on the length every resource agreed to skip.
The inputs are untrimmed, so a resource that needs the tokens being skipped can still read them.
- abstractmethod classmethod build(spec, info)[source]#
- Parameters:
spec (NodeResourceSpec)
info (EngineResourceInfo)
- Return type:
- build_cuda_graph_buffers(slots, max_bs, max_seq_len)[source]#
Size whatever the captured replays will read.
Called once per runner that captures against this node — the whole forward’s, and one per piecewise region — so it must tolerate repeated calls: grow to the largest shape asked for, never clobber what an earlier call already sized.
- Parameters:
slots (list[CGSlotSpec])
max_bs (int)
max_seq_len (int)
- Return type:
None
- can_reload(rid)[source]#
Whether the request can be reloaded. If this is False, the Engine will not attempt to reload. If True, it will attempt to reload but still check that the reload was successful.
- commit(step, ctx)[source]#
record step consumption
- Parameters:
step (ResourceStep)
ctx (StepContext)
- Return type:
None
- enable_prefix_cache(root, walks=None)[source]#
Open whatever this resource keeps across requests, under
root; True if anything opened.walksnames, per label, the walk that writes the keyed span and the one that decodes after it.
- extend_prefix_chain(rid, node_name, graph_walk, outputs)[source]#
Take this step’s sampled tokens, so what was generated can be keyed.
- fingerprint()[source]#
What this resource contributes to the prefix cache’s root.
Everything a stored page depends on beyond its own tokens. None leaves the resource out of the root, which is right only where it cannot change what a page holds.
- Return type:
bytes | None
- property force_double_buffer#
Whether this resource needs double-buffering even off the pre-plan path.
A resource that stages a step’s layout into a reused host buffer and issues a non-blocking H2D into a graph-read device buffer has a race the moment the CPU runs ahead of the GPU: plan(N+1) can overwrite the buffer before step N’s DMA has retired, and the replay attends with N+1’s data. The buffer need not be ours — FlashInfer’s
planholds one per wrapper, which is why the attention managers key theirs per slot. The main runner already double-buffers whenever a resourcesupports_preplan; this flag extends that to a runner that has no pre-plan path but still replays such a resource — notably the piecewise runner — and makes_exec_per_requestfence before it reuses a slot, since its sub-steps all run inside one step. Off by default; a resource opts in only if it has this hazard.
- get_offload_priority(rid)[source]#
How much this resource wants
ridgone, higher being more.Only consulted under a PRIORITY eviction policy, which names the resource to ask; LRU never calls it.
- ingest_request(rid, overrides)[source]#
- Parameters:
rid (str)
overrides (ResourceReqConfig | None)
- plan(step, ctx)[source]#
ret is immutable and opaque to runner; only gives to ctx.plan_results
- Parameters:
step (ResourceStep)
ctx (StepContext)
- Return type:
- post_warmup_validate()[source]#
For, e.g., the KV cache to check that num_free_pages is identical across TP ranks after cuda graph capture.
Raises an error (fails loudly) if invalid.
- publish(request_id)[source]#
- Parameters:
request_id (str)
- Return type:
PublishedInfo | None
- publish_after_stop(request_id, node_name, graph_walk)[source]#
Publish state that is useful only when a dynamic loop stops.
- Parameters:
- Return type:
PublishedInfo | None
- publish_for_step(request_id, node_name, graph_walk)[source]#
Publish after one node step, with context for selective exporters.
Existing resources remain compatible through
publish; resources that need node/walk context can override this method.- Parameters:
- Return type:
PublishedInfo | None
- reclaimable(rid)[source]#
What offload would free, in whatever this resource counts.
0 means the request holds nothing worth taking, so it is not an eviction candidate however cold it is. Distinct from get_offload_priority, which orders candidates rather than sizing them.
- resolve_cached_prefix(rid, node_name, graph_walk)[source]#
How many of this request’s leading tokens this resource already holds.
None leaves the length to other resources; 0 means nothing can be skipped.
- rollback_admit(step, ctx)[source]#
Give back whatever the live reservation for this step took.
Called on a refused admit, for every resource the step reached including the one that refused.
Only what was freshly taken. A page retained from a shared prefix, or a lease converted onto a stream, belongs to whoever else holds it.
- Parameters:
step (ResourceStep)
ctx (StepContext)
- Return type:
None
- property supports_eviction#
- property supports_preplan#
- class mstar.engine.resources.ResourceReqConfig[source]#
Bases:
objectPer-request parameters for one resource, carried on the request and handed to that resource at ingest. Keyed by resource key, so it needs no tag of its own — a marker base, with no contract beyond the hook below.
- class mstar.engine.resources.ResourceStep(segments: tuple[mstar.engine.resources.step.Segment, ...] | None = None)[source]#
Bases:
object
- class mstar.engine.resources.RingKVConfig(*, num_layers, num_kv_heads, head_dim, num_qo_heads=None, tokens_per_frame, layers, num_sessions=1)[source]#
Bases:
KVConfigA fixed horizon of frame slots per layer, overwritten in place.
Every layer’s storage is allocated once and reused for the life of the process, and a write to an occupied slot is the intended behaviour.
- Parameters:
- apply_yaml_overrides(num_sessions=None, **kwargs)[source]#
num_sessionsonly. Nothing else here is a deployment knob.- Parameters:
num_sessions (int | None)
- Return type:
None
- layers: tuple[RingKVLayerConfig, ...]#
- property total_sessions: int#
Resident sessions plus one shared scratch session for padding rows.
A replay padded to its capture bucket parks the dummy tail on this session (see
RingKVManager.plan); it is never handed to a request, so resident capacity staysnum_sessionsand the deployment knob keeps its meaning. The ring buffer and the flex mask both size on this count so the padding session is a real, addressable span.
- class mstar.engine.resources.RingKVLayerConfig(ring_frames, ring_buckets, pinned_dilation)[source]#
Bases:
objectOne layer’s ring geometry. Layers can hold frames at different strides.
- class mstar.engine.resources.RingKVStep(segments=None, *, frames)[source]#
Bases:
ResourceStepOne ring clock per request in the step’s batch.
- class mstar.engine.resources.SamplerSpec(resource_key: str, nodes: set[str], vocab_size: int | None, enable_repetion_penalty: bool = True, enable_min_p: bool = False)[source]#
Bases:
NodeResourceSpec- Parameters:
- class mstar.engine.resources.SamplerStep(segments: tuple[mstar.engine.resources.step.Segment, ...] | None=None, apply_penalty: bool = True, prefill_tracked_tokens: dict[str, torch.Tensor]=<factory>)[source]#
Bases:
ResourceStep- Parameters:
- class mstar.engine.resources.SamplingReqConfig(temperature: float = 0.6, top_k: int = 0, top_p: float = 1, ignore_eos: bool = False, repetition_penalty: float = 1, min_p: float = 0.0, _seed: int = 0)[source]#
Bases:
ResourceReqConfig- Parameters:
- property seed#
- class mstar.engine.resources.Segment(request_id, label, span)[source]#
Bases:
NamedTupleOne step’s addition to a request’s cache stream.
A request contributes one segment per label active for it in a step; the batch’s ordered segment list defines the layout of per-token arrays.
spanmay be 0: a zero-span segment reads its stream without extending it (admission reserves nothing, commit is a no-op).A NamedTuple, not a frozen dataclass: one is built per request per step, and the frozen dataclass’s
object.__setattr__-per-field __init__ is the expensive way to do that.
- class mstar.engine.resources.SlotLease(slot, bucket)[source]#
Bases:
objectattention admit gives to inform which slot to plan and replay
has no clean channel to plan/commit/release. see O.
- class mstar.engine.resources.StepContext(request_ids: collections.abc.Sequence[int], graph_walk: str, slot: int, capture: bool, is_preplan: bool = False, plan_results: dict[str, typing.Any] = <factory>, slot_lease: mstar.engine.resources.step.SlotLease | None = None, piecewise_leases: 'Mapping[str, SlotLease]' = <factory>, _padded_request_ids: collections.abc.Sequence[int] | None = None)[source]#
Bases:
object- Parameters:
- class mstar.engine.resources.StepRunner(resources, node_resources=None, enable_nvtx=False)[source]#
Bases:
objectdrives resources through per-step cycle
- Parameters:
- admit(step)[source]#
Reserve capacity for step. A refused admit gives back everything the step reserved.
- Parameters:
step (SubmoduleStep)
- Return type:
- admit_retrieve(rid, node_name, graph_walk, published=None)[source]#
bring published state in
gives ready=False when still has inflights; shortcircuit on failure
Swept over node_name’s own resources. Asking a node about resources it does not own is not just wasted work: KVManager.get_labels answers for an unrecognised node with the default [“main”], so the node ends up gated on — and able to allocate against — another node’s cache.
- Parameters:
- Return type:
- apply_cached_prefix(rid, node_name, graph_walk, inputs, matched_len)[source]#
Give every resource the agreed length, with the untrimmed inputs.
- build_cuda_graph_buffers(slots, max_bs, max_seq_len, node_name=None)[source]#
resources preallocate the static buffers captured replays will read
Swept over
node_name’s own resources: another node’s slot count and batch size say nothing about a resource this node’s graphs never touch.- Parameters:
slots (list[CGSlotSpec])
max_bs (int)
max_seq_len (int)
node_name (str | None)
- Return type:
None
- clear_preplan()[source]#
Drop the staged pre-plan on every resource, and the record of it.
- Return type:
None
- commit(step)[source]#
record step consumption
- Parameters:
step (SubmoduleStep)
- Return type:
None
- extend_prefix_chains(rid, node_name, graph_walk, outputs)[source]#
Offer this step’s sampled tokens to the node’s own resources.
- ingest_request(rid, overrides=None)[source]#
open state on all resources; overrides are per-resource
- Parameters:
rid (str)
overrides (Mapping[str, ResourceReqConfig] | None)
- Return type:
None
- plan(step)[source]#
plan in dependency order
place plan in step.ctx.plan_results before next plan runs again could possibly move that into plan itself
- Parameters:
step (SubmoduleStep)
- Return type:
- pre_admit(step)[source]#
admit over the pre-planning subset, a step ahead
the later full admit covers the rest; these resources see their own state as already reserved and no-op
Unwound on refusal exactly as
admitis.- Parameters:
step (SubmoduleStep)
- Return type:
- pre_plan(step)[source]#
plan the pre-planning subset, a step ahead
ctx.is_preplan sends each one’s output to its pending slot rather than the live one; the later full plan promotes it. Results are left in ctx.plan_results for the dependents in this same subset.
- Parameters:
step (SubmoduleStep)
- Return type:
- publish(request_ids, node_name=None, graph_walk=None)[source]#
durable state outward publish
non-publish resources noop; pairs with admit_retrieve
Scoped to the node whose step just ran; no other node’s state moved, and merge_publish_info keeps the entry it already published.
- publish_after_stop(request_ids, node_name=None, graph_walk=None)[source]#
Publish resources configured for the end of a dynamic loop.
- resolve_cached_prefix(rid, node_name, graph_walk)[source]#
The longest prefix every resource on
node_namecan serve.The smallest answer wins, because a step is one span: a resource that holds less than another has to be caught up by the tokens that run. A resource with no opinion is not an answer of zero.
- class mstar.engine.resources.SubmoduleStep(steps: dict[str, mstar.engine.resources.step.ResourceStep], segments: list[mstar.engine.resources.step.Segment] | None = None, cg_key_info: Any | None = None, _ctx: mstar.engine.resources.step.StepContext = None)[source]#
Bases:
object- Parameters:
steps (dict[str, ResourceStep])
cg_key_info (Any | None)
_ctx (StepContext)
- property ctx#
- get(key)[source]#
- Parameters:
key (str)
- Return type:
ResourceStep | None
- steps: dict[str, ResourceStep]#
- mstar.engine.resources.apply_yaml_overrides(specs, model_config)[source]#
Apply a deployment’s
resources:block to the specs it names.resources: {<resource_key>: {...}}, one block per resource, so a model with two pools of the same kind (whisper’s decoder cache and its encoder context) can have each tuned on its own. An unknown key is an error: it would otherwise be a silently ineffective setting.- Parameters:
specs (Sequence[NodeResourceSpec])
- Return type:
None
- mstar.engine.resources.resolve_spec_dependencies(specs)[source]#
Index specs by resource key, checking uniqueness and
depends_on.- Parameters:
specs (Sequence[NodeResourceSpec])
- Return type:
Modules