Runtime

Black-Box Failure Analysis of TinyRustLM

Report summary

This investigation was constrained to public evidence only: the live TinyRustLM site, MiniModel metadata, public MiRust/TinyRustLM implementation documentation, and authoritative external model documentation. I was able to inspect the live public UI state and the audited implementation/public manife

Status
Research archive item
Category
Runtime
Length
3,585 words
Reading time
17 minutes
Report type
evaluation

Key topics

  • Runtime
  • AI
  • Rust
  • GGUF
  • Semantic Systems
  • Research Archive
  • Strategy
  • Audit

Research provenance

Archive status
Research archive item
Content identity
sha256:9f19f53b86e10c9a588f8c0cc28a1c9f6b21d0efe4c546f88fd590fe3c557800

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

Source availability: 47 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

Scope and method

This investigation was constrained to public evidence only: the live TinyRustLM site, MiniModel metadata, public MiRust/TinyRustLM implementation documentation, and authoritative external model documentation. I was able to inspect the live public UI state and the audited implementation/public manifests, but I could not independently execute browser-controlled prompt runs from this environment without fabricating outputs. The report therefore separates directly observed public evidence from high-confidence engineering inferences and from explicit unknowns. That distinction matters here because the strongest public evidence already isolates several root causes before any prompt-level replay: the live UI shows a load-state failure, the public MiniModel demo catalog points to a synthetic smoke fixture, and the audited TinyRustLM implementation docs state that shipped artifacts are regression artifacts rather than assistant-quality models.

The most important conclusion is straightforward: the publicly visible behavior is not primarily explained by sampling knobs. It is explained first by artifact identity and runtime compatibility. The MiniModel example catalog exposes a synthetic q8 fixture with an 8,832-byte artifact, a tiny hidden=8, layers=1 shape, context 16, max_tokens/max_new_tokens of 16, and trained_quality_claim: "not-claimed". MiRust’s audited artifact catalog likewise says the supplied SLM artifacts are executable regression artifacts whose manifests explicitly deny trained assistant quality, and its runtime-smoke gate explicitly says a pass does not mean useful language behavior.

What the public evidence proves

The live public page currently shows a contradictory surface. It says it is “Loading the verified MiniModel demo”, then immediately presents “Something needs attention” and “Check the selected model and try again.” The same page shows the model selector headed by “SmolLM2 360M Instruct q4_0” and “SmolLM2 135M Instruct q8_0”, yet the runtime panel still says Model: waiting, benchmark counters remain zero, provenance fields remain waiting, and the footer says “No model loaded.” That is direct public evidence of a pre-generation load/state failure on the public chat surface.

A second contradiction appears when the live UI is compared with the audited implementation snapshot. The audited implementation says the browser boot sequence loads the default tinylm16q8 route, and that the selector maps to only eight fixed same-origin local .slm paths: TinyLM-16M in three quantizations plus five tiny fixtures. The same audited docs say TinyLM-16M-shaped options default to eight new tokens and tiny fixtures default to sixteen. That does not match the current live UI, which publicly renders a 1024-token preset and SmolLM2 labels first in the selector. The most plausible engineering reading is front-end/source drift or a metadata-first UI that is presenting candidate model labels not backed by the audited local artifact set.

The MiniModel public catalog also matters because it identifies what the “verified demo” actually is. MiniModel’s example catalog exposes tinyrustlm/tiny-test-model-q8, a synthetic fixture with artifact_byte_count: 8832, slm_model_shape: vocab=260,hidden=8,layers=1,...,context=16, quantization q8_0, source_kind: "synthetic", source_identity: "tinyrustlm-fixture-q8", quality_claim: "not-endorsed-by-project", and trained_quality_claim: "not-claimed". That is not a weak assistant. It is a deliberate execution/regression fixture.

MiRust’s artifact catalog and model pages reinforce that point. The audited catalog lists only eight bundled SLM artifacts: three TinyLM-16M variants and five tiny fixtures. It then states, plainly, that these artifacts are “executable regression artifacts” and that their manifests “explicitly deny trained assistant quality.” The specific TinyLM-16M q8 page further says its role is “runtime-smoke only” and that it has “Deterministic smoke weights; no trained assistant quality.”

There is also hard evidence that, even if the site were trying to use a real SmolLM2 model, the current runtime would not be a clean fit. SmolLM2-360M-Instruct’s official config shows num_attention_heads: 15 and num_key_value_heads: 5, which is Grouped Query Attention rather than equal-head MHA. TinyRustLM’s current implementation limitations page says the runtime currently requires equal attention and KV-head counts. That makes a real SmolLM2-360M-class import a compatibility problem unless there is an unpublished adapter or a runtime change not present in public evidence.

Finally, the public evidence shows a likely chat-format mismatch for any instruct-class model that might eventually load. The live UI’s transcript behavior documentation says each form submission sends only the current prompt field to generate, and earlier transcript turns are not concatenated automatically. Hugging Face’s SmolLM2 docs and tokenizer config show that the instruct model expects a chat template built around <|im_start|>...<|im_end|> messages, and Hugging Face’s chat-template docs warn that using a format different from the training format can cause severe, silent performance degradation. So even a successfully loaded SmolLM2-derived artifact would underperform badly without model-specific templating and conversational prompt serialization.

Raw evidence captures

The following short public captures are the most load-bearing pieces of evidence:

“Loading the verified MiniModel demo.”

“Something needs attention. Check the selected model and try again.”

“No model loaded”

“Load the default tinylm16q8 route.”

“Pass means the artifact is admitted for local runtime execution evidence. It does not mean useful language behavior.”

"trained_quality_claim": "not-claimed"

"num_attention_heads": 15 and "num_key_value_heads": 5

These captures also explain why there are no trustworthy screenshot attachments in this report: the available public tooling here can inspect and cite the live page text and public manifests, but it cannot safely fabricate browser-run screenshots or prompt outputs that were not actually executed.

Reproducible prompt matrix

Because I could not legally or technically fabricate 30 executed generations, the matrix below is a reproducible execution plan grounded in the public configuration state. For every row, the public live UI currently renders these inherited operator values: Max Tokens 1024, Temperature 0.70, Top-K 40, Top-P 0.90, with the selector headed by SmolLM2 360M Instruct q4_0 and SmolLM2 135M Instruct q8_0, while runtime state still says waiting and No model loaded. If the MiniModel demo actually resolves instead, the only publicly exposed example demo artifact is the tiny synthetic q8 fixture with context 16 and max tokens 16.

For each run, the local operator should record exactly the public runbook fields MiRust prescribes: prompt bytes or approved redacted prompt, model identity, sampling configuration, max token request, result message, numeric code, diagnostics JSON, browser elapsed time, and console entry. The diagnostics surface is documented to expose model-loaded state, last error, prompt/generated token counts, KV length, quantization mode, tokenizer output, logits summary, selected token, top-k summary, and active sampling configuration.

PromptProbe classWhat it testsExpected public-state outcome nowIf MiniModel demo actually loads
hellogreetingbaseline generationpre-generation load rejectiontrivial or nonsensical short output
hi theregreetingsame as abovepre-generation load rejectiontrivial short output
testambiguousdegenerate one-word promptpre-generation load rejectionrepetition or meaningless completion
continueambiguouscontinuation behaviorpre-generation load rejectionlikely repetition/collapse
what can you dogreetinginstruction followingpre-generation load rejectioncanned-looking but incoherent fragment
What is the capital of France?ordinary QAfactual retrievalpre-generation load rejectionlow-confidence trivial answer or nonsense
Why is the sky blue?ordinary QAexplanatory answerpre-generation load rejectionshallow fragment
Convert 37 C to F.short reasoningdeterministic arithmeticpre-generation load rejectionlikely wrong or trivial
If all cats are mammals and Milo is a cat, what is Milo?short reasoningsyllogismpre-generation load rejectionweak or incoherent
Which is larger, 0.5 or 0.05?short reasoningtoken-level comparisonpre-generation load rejectionmay be right by chance, not evidence of assistant quality
Rewrite this sentence professionally: “send me the file asap”rewritingstyle transferpre-generation load rejectiontoo short/trivial to be useful
Rewrite to plain English: “The implementation exhibits nondeterministic boundary behavior.”rewritingparaphrasepre-generation load rejectionfragmentary
Summarize: Rust emphasizes memory safety without garbage collection.summarizationshort summarypre-generation load rejectionlikely truncation
Summarize in one sentence: Tiny models can run locally in a browser.summarizationone-sentence abstractionpre-generation load rejectionmay emit trivial echo
Explain this code: for (const x of xs) total += x;code explanationcode understandingpre-generation load rejectionshallow or incomplete
Explain what a mutex does in multithreaded code.code explanationsystems concept explanationpre-generation load rejectionweak fragment
Output exact JSON only: {"ok":true,"items":[1,2,3]}exact JSONstrict structured outputpre-generation load rejectionlikely invalid JSON
Output exact JSON only with keys name, age: Alice, 30exact JSONschema obediencepre-generation load rejectionlikely malformed JSON
Respond with only the word blueexact constrained outputstrict decodingpre-generation load rejectionmay still drift
First turn: My favorite color is green.multi-turnmemory setuppre-generation load rejectionstored only in transcript, not serialized for next turn
Second turn: What is my favorite color?multi-turn follow-upconversational carry-overpre-generation load rejectionprior turn ignored by UI path
First turn: I live in Denver.multi-turnmemory setuppre-generation load rejectionsame limitation
Second turn: Where do I live?multi-turn follow-uptranscript/context serializationpre-generation load rejectionprior turn ignored
Summarize this 5-paragraph article...long contextprompt budget and truncationpre-generation load rejectionlikely context exceeded or useless truncation
Extract three themes from this 2-page text...long contextsustained context usepre-generation load rejectionlikely context exceeded
Repeat the word “data” 50 times.adversarial repetitionrepetition stabilitypre-generation load rejectionrepetition collapse likely
Continue ha ha ha ha ha ...adversarial repetitionloop behaviorpre-generation load rejectionrepetition collapse likely
Complete the pattern: A A A A Aadversarial repetitiondegeneracy resistancepre-generation load rejectionrepetitive degeneration
Write a 200-word product description for a backpack.ordinary generationextended coherencepre-generation load rejectionimpossible under 16-token demo budget
Give me two concise pros and two cons of local inference.ordinary reasoninglist structurepre-generation load rejectionincomplete/trivial

Two engineering notes matter for interpreting this matrix. First, the live public state suggests that many of these rows will currently fail before generation because no usable model is loaded. Second, if the MiniModel demo is what eventually loads, the public artifact metadata makes it unsuitable for this matrix by construction: context 16, output 16, synthetic/non-trained source, and no assistant-quality claim.

Failure taxonomy ranked by confidence and impact

The table below ranks the user’s proposed failure classes by public-evidence confidence and practical impact.

Failure originConfidenceImpactWhy
Deliberately untrained execution fixtureVery highCriticalPublic MiniModel metadata identifies the example demo as a synthetic fixture with no trained-quality claim, and MiRust’s artifact catalog says bundled artifacts are regression artifacts rather than assistant-quality models.
Tiny output budgetVery high for the MiniModel demo; high overallHighThe public MiniModel demo example exposes context 16 and max output 16. The audited selector defaults are also only 8 tokens for TinyLM and 16 for tiny fixtures. That is enough to force trivial, clipped, or apparently “stupid” behavior.
Context serialization failureVery highHighMiRust’s UI/transcript docs say each submission sends only the current prompt and does not auto-serialize previous turns into the next prompt. That breaks follow-up questions even with a good instruct model.
Front-end/source drift around advertised defaultHighHighThe live site publicly advertises SmolLM2 selector entries and 1024-token creative-style defaults, while the audited runtime docs describe eight fixed local SLM routes and a default tinylm16q8 load path.
GQA and KV-head incompatibilityHigh for SmolLM2-class modelsHighSmolLM2-360M-Instruct uses 15 attention heads and 5 KV heads, while TinyRustLM publicly documents a current equal-head-count requirement. That is a compatibility blocker, not a quality tweak.
Chat-template mismatchHigh for instruct modelsHighSmolLM2’s official tokenizer config requires an `<
Browser/WASM resource limitsHighMedium to highTinyRustLM publicly documents full-file copy, a 128 MiB single-transfer cap, synchronous main-thread execution, and no worker or cancellation. Those limits make larger useful defaults difficult and can degrade UX severely.
Weak trained weightsLow as current primary explanationMediumThere is no public evidence that the live default is a merely weak trained model. The strongest evidence points instead to smoke fixtures and/or incompatibility before generation.
Quantization damageLow to medium as current primary explanationMediumq4 can absolutely reduce quality, but the public evidence already explains failure without invoking quantization damage: smoke fixtures, tiny budgets, and incompatibility. Quantization would be secondary here.
Incorrect BOS/EOS/control-token handlingMedium as a future conversion risk; low as proved current causeMediumTinyRustLM’s tokenizer contract uses reserved control IDs and explicit BOS/EOS handling, while SmolLM2 uses its own special-token scheme. That is a real integration risk, but no public converted SmolLM2 SLM artifact is available to prove a live mismatch.
Tokenizer incompatibilityMedium as a future conversion risk; low as proved current causeMediumTinyRustLM can convert trained sources to SLM1 and embeds a tokenizer contract, but no public converted-trained SmolLM2 artifact is exposed for direct validation. So incompatibility is plausible, not yet proven.
Sampling parametersMedium as an amplifier; low as root causeLow to mediumThe live UI renders temp=0.70, top-k=40, top-p=0.90, but the audited runtime originally documented deterministic defaults. Sampling affects style and repetition, but it does not explain “No model loaded,” non-trained fixtures, or GQA mismatch.
Repetition penaltyVery lowLowNo repetition-penalty control is exposed in the live selector panel or the public sampler docs. Public evidence does not support this as a root cause.
Quality-gate false positivesMediumMediumPublic provenance and smoke-gate docs show a real trust/interpretation gap: artifacts can look “verified” or “admitted” while still carrying no assistant-quality claim, and sidecars are informational rather than binding admission authority. That is a labeling/governance false-positive more than a text-generation false-positive.

The short version is that the failure stack is layered, but its root is not subtle. The first-order cause is that the publicly surfaced “demo/default” path is tied to non-assistant artifacts or to an unresolved load path. The second-order causes are that the runtime, as publicly documented, lacks the compatibility features needed for a real modern instruct model such as SmolLM2, and the UI lacks the prompt-formatting and context-serialization behavior such a model expects.

Immediate, intermediate, and architectural corrections

The immediate correction is not to “fix responses.” It is to stop presenting a regression fixture as if it were a useful local assistant default. The public chat surface should either ship with no autoloaded chat model or it should autoload only a converted-trained artifact that has actually passed the assistant-quality gate. MiRust’s own public docs already define that boundary: assistant-quality requires source_kind = converted-trained plus evaluation sidecars and a quality decision accepted for assistant-quality, while the current fixture explicitly is not product evidence.

The second immediate correction is to make the selector truthful. If a selector row is only metadata discovery or a future conversion candidate, it should not appear as a ready local runtime choice beside actual loadable .slm routes. The audited selector contract says a selector entry proves only that the static application knows a route; it does not prove runtime acceptance or quality. The live UI should therefore clearly separate verified local artifacts, importable local files, conversion candidates, and metadata-only model cards.

The third immediate correction is to bind prompt construction to model identity. For instruct models, TinyRustLM needs a model-specific chat-template layer and it needs to serialize prior turns into the next prompt. Right now the public docs say the UI sends only the current turn, and Hugging Face explicitly warns that using the wrong training format causes severe silent degradation. This is one of the highest-return fixes because it improves every future trained model without weakening any safety or quality gate.

Intermediate work should focus on real compatibility rather than cosmetics. The runtime needs GQA-capable attention and KV-cache handling if it wants to support current instruct models such as SmolLM2-360M. It also needs a worker-owned runtime so generation moves off the main thread, because the public docs say the current monolithic generate call is synchronous and non-cancellable. Finally, it needs verified artifact admission and a persistent local artifact store so the browser is not forced to refetch and recopy full model files on each usage path.

Architecturally, the project should decide whether it wants to remain an SLM1-only custom-runtime experiment or become a credible browser LLM runtime. Its own roadmap already points in the right direction: trained-model admission, worker ownership, a verified local store, and a true compatibility path rather than aliasing formats. Public MiRust docs explicitly say current TinyRustLM has no GGUF parser, uses scalar CPU loops, supports one model at a time, and still treats provenance sidecars as informational rather than authenticating admission. A production path needs those boundaries closed, not hidden.

Proposed production default and quantitative targets

Under the current publicly documented runtime constraints, the only plausible production default that could provide useful language behavior is not SmolLM2-360M-Instruct q4_0 and not SmolLM2-135M-Instruct q8_0. Public file sizes make both of those bad fits for the current architecture: the current runtime has a 128 MiB single-transfer ceiling, SmolLM2-135M-Instruct Q8_0 is publicly listed at 0.14 GB, and SmolLM2-360M-Instruct Q4_0 is publicly listed at 0.23 GB. Both exceed the present transfer model’s practical ceiling. By contrast, SmolLM2-135M-Instruct Q4_0 is publicly listed at about 0.09 GB, which is the only one of the obvious candidates that fits the current transfer envelope.

So the best near-term production default is this:

Converted-trained SmolLM2-135M-Instruct q4_0 in SLM1, with model-specific chat template application, multi-turn prompt serialization, truthful provenance labeling, and assistant-quality gate acceptance. That is the highest-utility model choice that is still compatible with the public runtime’s current size ceiling, assuming the runtime is extended far enough to support the model’s tokenizer/control-token semantics and its instruct chat template.

Once the runtime adds worker execution, chunked/verified loading, persistent storage, and GQA support, the better long-term default becomes SmolLM2-360M-Instruct in a browser-suitable quantization, because the 360M class is explicitly intended for compact on-device use and is meaningfully more capable than the 135M class. But that should be a phase-two default, not a launch default for the current implementation.

The quantitative targets below are therefore proposed engineering targets, not claims about current TinyRustLM performance:

Target areaImmediate realistic targetIntermediate targetArchitectural target
Default artifact download≤ 100 MiB so it fits the current 128 MiB transfer ceiling with margin≤ 250 MiB with chunked verified store≤ 400 MiB for “high-quality browser default” tier
Peak browser memory during default load≤ 512 MiB total working set≤ 768 MiB with worker + persistent store≤ 1.5 GiB for extended-quality tier
Time to usable first response< 4 s on desktop broadband< 2 s after warm cache< 1 s warm start with persistent verified store
Decode rate≥ 8 tok/s desktop, ≥ 3 tok/s mid-tier mobile≥ 15 tok/s desktop, ≥ 5 tok/s mobile≥ 25 tok/s desktop warm-cache
Output budget≥ 128 new tokens truthful hard cap≥ 256≥ 512
Context budget≥ 2,048 tokens effective user-visible cap≥ 4,096≥ 8,192
Browser compatibilitylatest two stable releases of Chromium, Firefox, Safari desktopplus current Android Chrome and iOS Safarisame, with persistent-store recovery and worker-based cancellation everywhere

Those targets are chosen to close the precise public gaps identified above: the current transfer cap, the current lack of worker execution, the current main-thread sync path, the current lack of persistent artifact storage, and the current mismatch between a useful instruct model and the runtime’s admitted artifact set.

Explicit unknowns that public evidence cannot establish

Several things remain unknowable from public evidence alone.

First, I cannot truthfully provide a completed table of 30 executed prompt outputs, latencies, and token counts from this environment, because I could not independently drive the live site through all prompt submissions. Public evidence supports the diagnosis, but it does not justify invented run outputs.

Second, I cannot establish whether the SmolLM2 selector entries on the live page are inert labels, metadata-only candidates, pending conversion routes, or real loadable artifacts backed by an unpublished runtime build. The public implementation audit from 2026-06-25 says the selector maps to eight fixed local SLM artifacts, while the live site now renders SmolLM2 choices. That discrepancy is real, but its exact operational cause is not public.

Third, I cannot establish whether a real converted-trained SmolLM2 SLM artifact exists privately and merely failed to load, or whether the live UI is attempting to bootstrap only the MiniModel fixture and never reaches a trained model path. No public signed manifest or artifact bytes are available to settle that. MiniModel’s public example content is still only the tiny synthetic fixture.

Fourth, I cannot prove a current tokenizer/BOS/EOS/control-token bug in a real trained artifact path. I can show that TinyRustLM has an explicit tokenizer/control-token contract and that SmolLM2 expects its own special tokens and chat template, but without a public converted SmolLM2 SLM and a reproducible run, that remains a plausible integration risk rather than a demonstrated live bug.

Fifth, I cannot prove the existence of a separate post-generation rejection filter that is falsely discarding otherwise good model text. The public evidence I found points to model-load/state rejection and to artifact-quality mislabeling, not to a hidden response-quality filter rejecting outputs after successful generation.

Taken together, the public evidence is still enough to reach a strong engineering verdict: TinyRustLM’s bad default behavior is best explained by the wrong artifact class on the chat surface, incompatible or unresolved runtime/model wiring, and missing instruct-model prompt serialization, not by a merely “weak model” and not by superficial sampling tweaks.