backends¶
Responsibility¶
Generate assistant text for a rendered snapshot, audio parts included where the model hears them, and return a
GenerationRecord; optionally reuse prompt-prefix state and compute model embeddings.
Public surface¶
All backends take a
PluginContextand readcontext.config.backend;generate(snapshot, generation: GenerationConfig).MockBackend(mock): deterministic text from a SHA-256 of the snapshot id, each message’smessage_chat_text, model id and generation parameters; at most 16 four-character tokens; used in continuous integration (CI).MockAudioBackend(mock_audio, subclass ofMockBackend): echoes each message’s words, then one token per voiced run of eachAudioPart(amplitude aboveSILENCE0.01, runs split byMIN_GAP_S0.01 s) (decision). 16-bit WAV decodes withwave; other formats usedecode_audio(audioextra).ApiBackend(api): OpenAI-compatible application programming interface (API)/chat/completionsoverhttpx, withTimeout(backend.timeout_s)and at mostmax_inflightconnections.Retries
RETRYABLE_STATUS(408, 429, 5xx gateway codes) and transport errors up tobackend.max_retrieswith exponential backoff, honouringRetry-Afterup totimeout_s. Non-JSON responses raiseBackendUnavailableError.snapshot_to_api_messages: a message with audio sends its text part, then one base64 WAVinput_audiopart perAudioPart(non-WAV re-encoded).Sends
"logprobs": true;extract_logprobsreadschoices[0].logprobs.content[*].logprob, elseNone; an empty reply gets()(LM Studio sendsnull), whichlogprobscores 0.returns_logprobsis true (SupportsLogprobs).Caches temperature-0 records (text and logprobs) in an LRU of
RESPONSE_CACHE_SIZE(1024).backend.api_hostis required (ConfigErrorwithout it; no environment or localhost fallback).Bearer key
MLLM_SHAP_API_KEYfor any host;OPENAI_API_KEYonly forapi.openai.com.
LmStudioBackend(lmstudio): local LM Studio server through thelmstudioSDK.LmStudioOptions(hub_search,quantization,auto_download,serialize_generate,audio) come frombackend.options; unknown keys raiseConfigError.audio: refuse(default) raisesValueErroron audio;transcriptsends the text parts and warns once. The SDK (1.6.0b1 included) takes no audio.match_downloaded_model_keymatches exactly, then by last-segment prefix, then by substring, and raises on ambiguity;pick_search_resultraises unless a hub hit matches the name.Retries once, only on transient connection errors (
_is_transient).Records carry no logprobs (the SDK exposes none).
TransformersTextBackend(transformers): Hugging Face model on CUDA (Compute Unified Device Architecture), MPS (Metal Performance Shaders) or CPU.TransformersOptions:dtype(autopicks bfloat16 where supported, float16 on other accelerators, float32 on CPU),revisionandmodel_class.A config in
MODEL_FOR_CAUSAL_LM_MAPPINGloads as text; any other (ormodel_class) loads its class withAutoProcessor(decision).audio.processor_inputsresamples audio to the processor rate and drops empty parts. It sends structured parts when the chat template mentions audio, else oneaudio_tokenper part.Encoding, generation and decoding share one model lock.
With the key-value (KV) cache enabled (
SupportsKvCache),_attach_prefix_cachecopies and crops the longest cached prefix and runs only the uncovered tokens.;kv_cache_hitsandkv_cache_reused_tokenscount the reuse.Static and contextual embeddings are computed only when
generation.compute_embeddingsis set.generatereturns raw logits (output_logits);_token_logprobstakes their log-softmax at each generated token, end-of-sequence included.returns_logprobsis true.
backends/_chat.py:snapshot_has_audio,chat_role,message_chat_text("<speaker>: <text>"unless the text is empty; speaker rendering),snapshot_to_chat_messages.
Data flow¶
In: rendered
ConversationSnapshotandGenerationConfigfrom the pipeline orchestrator;PluginContextat construction.Out:
GenerationRecordbuilt withvalue.generation_records.generation_record_from_text(text)(value), with model embeddings when requested; other backends have none, so their records equal thosereanalyzebuilds.Optional dependencies (
httpx,lmstudio,torch,torchaudio,transformers) are imported lazily; a missing extra raisesBackendUnavailableError(core).
Invariants¶
Audio prompts skip the prefix cache; a text model and
lmstudio(unlessaudio: transcript) refuse audio withValueError;mockhashes text and the snapshot id only.mock_audio: a run’s token depends on its samples only, so silencing or cutting another run leaves it unchanged.In float32, greedy transformers outputs are identical with the prefix cache on and off, and their logprobs agree within 1e-4; in float16 and bfloat16 they agree up to rounding, and the backend warns once (decision). No prompt token is processed twice.
A backend injected into
ExplainRunneris reused across calls and closed by the runner; otherwise one backend is built and closed perexplain().
Known issues¶
None open. Fixed: C06, C08, C15, D02, D04, D05, D07 (Fixed issues).