Runtime

Real-Browser WASM Qwen3 Execution Under Honest Memory And Isolation Limits

Report summary

The deployment of a roughly 0.6-billion-parameter, 598 MB mixed-Q8 Qwen3 Small Language Model (SLM2) strictly within a client-side web browser necessitates an architecture that prioritizes rigid memory bounding, zero-copy data streaming, and absolute execution determinism. The recommended architectu

Status
Research archive item
Category
Runtime
Length
5,245 words
Reading time
24 minutes
Report type
guidance

Key topics

  • Runtime
  • AI
  • .NET
  • SQL
  • Rust
  • GGUF
  • Privacy
  • Semantic Systems

Research provenance

Archive status
Research archive item
Content identity
sha256:bf9cb2b02b86fe5e399b74ef80b8172af8d562e28dc65f989ef5368c04865f75

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

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

1. Executive Browser Architecture Recommendation

The deployment of a roughly 0.6-billion-parameter, 598 MB mixed-Q8 Qwen3 Small Language Model (SLM2) strictly within a client-side web browser necessitates an architecture that prioritizes rigid memory bounding, zero-copy data streaming, and absolute execution determinism. The recommended architecture for the TinyRustLM project mandates the utilization of the WebAssembly 32-bit (WASM32) standard, augmented by Bulk Memory, Atomics, SIMD128, and the recently standardized Relaxed SIMD extension, executing entirely within a dedicated, cross-origin isolated Web Worker. Despite the advent of the WebAssembly 3.0 specification and its inclusion of Memory64—which theoretically expands the linear memory address space from the historical 4 GB limit up to 16 GB in modern browser engines1—WASM32 remains the superior and mandatory target for this specific 598 MB model classification. Memory64 introduces inherent addressing overhead, increasing memory access latency by approximately 10% on highly optimized execution paths due to the browser engine's necessity to perform 64-bit pointer bounds checking1. Because a 598 MB immutable model, coupled with a bounded Key-Value (KV) cache and deterministic intermediate scratch space, can comfortably execute within a statically allocated 1.5 GB WASM32 linear memory, the performance penalty and trailing mobile browser support associated with Memory64 are architecturally unjustified. The paramount constraint governing this architecture is the absolute prohibition of dynamic memory growth via the memory.grow instruction. Modern Chromium architectures, utilizing the V8 JavaScript engine, enforce security and memory management through a 4 GB pointer compression cage (the V8 Sandbox)5. Dynamically expanding the WebAssembly linear memory frequently exhausts contiguous virtual address space, forcing the underlying PartitionAlloc memory allocator to relocate the ArrayBuffer backing store8. This relocation triggers catastrophic de-optimization of the TurboFan Just-In-Time (JIT) compiled code, leading to severe memory fragmentation, stale JIT pointers, out-of-memory (OOM) renderer process terminations, and sandbox escape vulnerabilities8. Consequently, the WebAssembly memory must be instantiated with identical initial and maximum page counts, establishing an unyielding, pre-allocated boundary. Storage and instantiation must rely exclusively on the Origin Private File System (OPFS), utilizing synchronous FileSystemSyncAccessHandle operations to read model bytes directly into the pre-allocated WASM linear memory12. This circumvents the JavaScript garbage-collected heap entirely, achieving true zero-copy deserialization. Conformance is rigidly verified via streaming cryptographic hashes before execution, and all threading and cancellation mechanisms must rely on cooperative Atomics over a SharedArrayBuffer to prevent main-thread event loop blocking. Server inference fallbacks, JavaScript engine fallbacks, and invisible retry mechanisms are strictly prohibited by the system design.

2. Current Standards and Browser Capability Matrix

The browser execution environment is strictly defined by the intersection of normative WebAssembly standards and specific engine implementation limits. The following matrix delineates the capabilities required to execute the Qwen3 SLM2, distinguishing between universally supported standards and features requiring explicit local probing.

WebAssembly and Browser Capability Matrix

Capability / StandardChromium (v133+)Firefox (v134+)WebKit / Safari (v18.4+)Architectural Impact
WASM32 Addressability4 GB4 GB4 GBImposes a hard 4 GB ceiling. Requires Rust toolchains to utilize \-C link-arg=--max-memory=4294967296 to unlock the full 32-bit address space15.
Memory64 StatusFully Supported16Fully Supported1Tech Preview / Flagged4Avoided due to \~10% pointer-math overhead and incomplete mobile ecosystem penetration2.
SharedArrayBuffer (SAB)SupportedSupportedSupportedMandatory for establishing a zero-copy command/event ring buffer between the UI thread and the Web Worker.
SIMD128SupportedSupportedSupportedBaseline requirement for vectorization of all non-dot-product kernels (e.g., RoPE, RMSNorm)17.
Relaxed SIMDSupported (Wasm 3.0)20Supported20Supported20Enables relaxed\_dot\_i8x16\_i7x16\_s for mixed-Q8 matrix multiplications, trading numerical determinism for AVX/VNNI hardware mapping20.
OPFS SyncAccessHandleSupported (Workers only)23Supported (v111+)23Supported (v15.2+)24Permits direct, synchronous disk-to-WASM-memory mapping without JS garbage collection serialization overhead14.
Streaming CompilationSupportedSupportedSupportedWebAssembly.instantiateStreaming is critical to overlap V8 Liftoff baseline compilation with local OPFS disk reads26.
CSP wasm-unsafe-evalSupportedSupportedSupportedMandatory in the script-src directive to permit WASM JIT compilation without violating strict content security policies29.

The WebAssembly 3.0 standard formalizes Relaxed SIMD, which allows browser engines to map specific instructions directly to underlying hardware instructions without enforcing strict cross-architecture numerical determinism20. In the context of a Chromium execution requirement, the V8 engine maps the i32x4.relaxed\_dot\_i8x16\_i7x16\_add\_s instruction directly to vpdpbusd (AVX2-VNNI or AVX512-VNNI) on x86-64 architectures, and to equivalent sdot instructions on ARM22. This matrix verifies that a unified WASM32 binary, leveraging SIMD128 and Relaxed SIMD, can be safely deployed across modern browser architectures, provided a scalar fallback is compiled into the binary to handle older mobile clients that fail a runtime feature probe.

3. Peak-Memory and Copy-Count Model

Assuming a 598 MB file consumes only 598 MB at runtime constitutes a fundamental architectural failure that guarantees browser tab termination via the OS out-of-memory (OOM) killer. A precise peak-memory equation is required, mapping every byte of the Qwen3 0.6B architecture to the WebAssembly linear memory and the browser's native heap. The structural parameters for the Qwen2.5/3 0.6B model class dictate the memory geometry:

  • Vocabulary Size: 151,93632
  • Hidden Size ([Figure omitted from source export]): 89633
  • Intermediate (MLP) Size: 4,86434
  • Hidden Layers: 2432
  • Attention Heads ([Figure omitted from source export]): 1434
  • Key-Value Heads ([Figure omitted from source export]): 2 (Grouped Query Attention)34
  • Maximum Sequence Length: 8,192 tokens.

Exact Memory Allocation Equation

The total resident memory footprint ([Figure omitted from source export]) consists of the immutable model bytes ([Figure omitted from source export]), the Key-Value Cache ([Figure omitted from source export]), activation scratch space ([Figure omitted from source export]), worker messaging buffers ([Figure omitted from source export]), and the browser engine's internal JIT compilation overhead ([Figure omitted from source export]). [Figure omitted from source export] 1\. Immutable Model Bytes ([Figure omitted from source export]): The model is quantized utilizing a mixed-Q8 format, specifically mapping to the GGML Q8\_0 structure. This format stores 32 int8 weights alongside a single 2-byte fp16 scaling factor, consuming exactly 34 bytes per block (yielding 8.5 bits per weight)37. For approximately 560 million quantized parameters—excluding the fp16 embeddings, layernorm scales, and biases—the exact memory footprint maps to approximately 598 MB. This data must exist exactly once in the linear memory, loaded via a zero-copy operation. 2\. Key-Value Cache ([Figure omitted from source export]): Utilizing Grouped Query Attention (GQA), each token requires storing keys and values for exactly 2 heads. The dimension per head ([Figure omitted from source export]) is calculated as [Figure omitted from source export]. The byte requirement per token per layer is: [Figure omitted from source export]. Total bytes per token across all 24 layers equals [Figure omitted from source export]34. To support a bounded context window of 8,192 tokens, the KV cache requires a static allocation of [Figure omitted from source export]. 3\. Execution Scratch Space ([Figure omitted from source export]): During the prefill phase, processing a chunk of tokens requires activating the 4,864-dimension SwiGLU intermediate layer34. The maximum activation tensor for a batch size of 1 and a prefill sequence of 2,048 tokens is [Figure omitted from source export]. Logits calculation over the massive 151,936 vocabulary requires [Figure omitted from source export]32. The total bounded scratch space, including memory for RoPE positional arrays and intermediate attention matrices, is safely capped at 64 MB. 4\. Worker Messaging ([Figure omitted from source export]) & JavaScript Copies: By utilizing a SharedArrayBuffer (SAB) for communication between the UI thread and the worker, JavaScript whole-file copies are strictly eliminated. [Figure omitted from source export] for the model weights, and the SAB ring-buffer for command/event passing consumes exactly 1 MB27. Accidental whole-file copies via postMessage structural cloning are architecturally banned. 5\. Compiler/JIT Overhead ([Figure omitted from source export]): The V8 engine compiles WebAssembly using the Liftoff baseline compiler initially, followed by the TurboFan optimizer running in background threads26. The compilation graph, instruction selection algorithms, and sea-of-nodes intermediate representation consume immense native, off-heap memory. Compiling a dense WASM binary can spike V8's native heap by up to 160 MB during the TurboFan tier-up phase41.

The Strict Allocation Strategy

To prevent V8 PartitionAlloc fragmentation within the 4 GB pointer compression cage, the WebAssembly memory must be initialized with no capability to grow6.

JavaScript // 1.5 GB static allocation encompasses all equations securely, leaving room for V8 overhead const STATIC\_PAGES \= 24000; // 24000 \* 64KB \= 1,572,864,000 bytes const wasmMemory \= new WebAssembly.Memory({ initial: STATIC\_PAGES, maximum: STATIC\_PAGES, shared: true });

This immutable allocation strategy ensures the backing ArrayBuffer is mapped contiguously exactly once, rendering the application impervious to memory.grow OOM termination faults and protecting against stale pointer vulnerabilities in the JIT compiler8.

4. Storage, Streaming Load, and Atomic Activation

The product deployment constraints dictate that model bytes must remain purely local or travel directly between consenting peers via P2P. The primary local storage mechanism must be the Origin Private File System (OPFS), which provides high-performance, byte-by-byte access to virtual file structures directly from a Web Worker context14.

Storage and Load Path Comparison

1. IndexedDB Blobs: Strictly rejected. IndexedDB requires asynchronous event loops and forces the browser's storage thread to serialize data, inherently instantiating detached ArrayBuffer copies on the main JavaScript heap before the data can be transferred14. This guarantees peak memory violations.

2. File System Access Handles (Main Thread): Rejected. Prompts the user and cannot provide synchronous reads, blocking the UI thread during massive buffer transfers.

3. OPFS SyncAccessHandle (Worker Thread): The required path. Inside a Web Worker, OPFS exposes FileSystemSyncAccessHandle, which allows the application to execute synchronous, blocking read() operations. Crucially, this API allows passing a Uint8Array view of the WebAssembly memory directly into the read function, pulling bytes from disk into the WASM linear memory with absolute zero-copy semantics12.

Bounded Streaming SLM2 Loader Design

1. Header-First Admission: The first 4,096 bytes of the OPFS file are read synchronously. The WASM loader parses the file magic numbers, extracts the metadata manifest, and verifies that the tensor structures conform to the expected Qwen3 Q8\_0 format and correct dimensionality12.

2. Streaming Verification: The 598 MB file must not be executed if compromised. However, a Web Worker cannot duplicate a 598 MB file into a separate buffer to hash it without risking an OOM event. Instead, the file is read in 4 MB chunks. The WebCrypto API crypto.subtle.digest("SHA-256", chunk) is utilized to provide an incremental, streaming hash validation of the data as it is read46.

3. Direct-to-Heap Transfer: Once the header is validated, the remaining tensor pages are read directly into the pre-allocated WASM linear memory offset designated for [Figure omitted from source export].

Atomic Activation

To prevent partial or corrupted loads from entering the inference loop, the worker implements an atomic state machine. The WASM execution engine is locked (via Atomics.wait on a designated status address in the SAB) until the streaming SHA-256 hash perfectly matches the embedded manifest hash. If the cryptographic hash fails, the WASM memory region is zeroed, the worker emits a fatal validation error to the main thread, and the corrupted OPFS entry is scheduled for permanent deletion via removeEntry14. Only upon an exact hash match is the atomic lock released, transitioning the worker to a verifiable READY state.

5. Scalar/SIMD WASM Kernel Contract

The Qwen3 architecture relies heavily on computationally dense operations: matrix-vector multiplications for linear layers, Root Mean Square Normalization (RMSNorm), Rotary Positional Embeddings (RoPE), and SwiGLU activations. To achieve acceptable tokens-per-second, these kernels must be strictly typed and rely on a defined hardware contract via WebAssembly SIMD.

Q8_0 Mixed-Precision Matrix Multiplication

The GGML Q8\_0 format stores 32 int8 weights and one fp16 scaling factor per block37. During inference, the fp32 activations from the previous layer are dynamically quantized into Q8\_0 format per row before the dot product is calculated. The WASM SIMD contract mandates the use of the 128-bit vector width (16 lanes of 8-bit integers). For maximum throughput, the linear layer kernel utilizes the WebAssembly Relaxed SIMD standard, specifically relying on the i32x4.relaxed\_dot\_i8x16\_i7x16\_add\_s instruction20. Kernel Specifications:

1. Alignment: Weight blocks mapped into the linear memory must be 16-byte aligned to prevent boundary-crossing penalties during 128-bit SIMD loads.

2. Lane Width & Integer Widening: The instruction processes two 128-bit vectors. The activation row is dynamically quantized to int8. The Wasm specification for relaxed\_dot implies one operand is treated as signed 8-bit and the other as unsigned 7-bit, or bounded signed20. To prevent undefined saturation artifacts in V8's translation to AVX2-VNNI vpdpbusd, the dynamic quantization logic must strictly bound the activation integers to \[-127, 127\]22.

3. Tails: Sequence lengths and intermediate matrix dimensions that are not multiples of the block size (32) must be padded with explicit zeros during dynamic activation quantization to prevent out-of-bounds reads.

4. Floating Reduction Order: The integer dot product result is accumulated into four i32 vectors. This is horizontally added, converted to f32 (f32x4.convert\_i32x4\_s), and multiplied by the block's fp16 scale (which is promoted to f32 via a lookup table or direct cast).

Auxiliary Kernels: RoPE and RMSNorm

  • RoPE Kernel: Qwen3 Rotary Positional Embeddings apply complex rotations to the Query and Key heads. This is implemented using standard f32x4.mul and f32x4.add instructions across interleaved lane permutations executed via v128.shuffle.
  • RMSNorm: Requires calculating the inverse square root of the mean of squares. To maintain numerical stability and avoid differences in browser JIT implementations of 32-bit floating-point math, the reduction sum is accumulated in strictly deterministic f64 precision. Only after the final inverse square root is calculated is the scalar cast back to f32 for the normalization multiplication against the layer inputs.

Feature Detection and Rejection

The compiled WASM module must export a probe\_features() function. During initialization, this function attempts to execute a single relaxed\_dot instruction inside a WASM trap-handler equivalent block. If the host V8 engine does not support Relaxed SIMD (e.g., an outdated mobile Chromium build), the engine will trap. The WASM state machine catches this, and transparently hot-swaps the matrix-multiplication function pointer to a standard SIMD128 implementation utilizing i16x8.extmul\_low\_i8x16\_s and i32x4.extadd\_pairwise\_i16x8\_s. This incurs roughly a 30% penalty in generation throughput but guarantees strict conformance on legacy hardware.

6. Worker Protocol and State Ownership

JavaScript main-thread execution of SLM inference is expressly prohibited. Prolonged synchronous execution blocks the browser's event loop, dropping frames and rendering the UI unresponsive27. Execution must occur in a dedicated Worker. The worker thread maintains strict, exclusive ownership over the WASM linear memory, the KV cache state, and the OPFS file handles. The UI thread is merely a thin rendering client.

Messaging Bounding and The Ring-Buffer Protocol

To prevent unbounded queues and duplicate rendering, the UI thread must not stream tokens by dispatching infinite postMessage events. Unbounded messaging forces the serialization of the V8 structured clone algorithm, leading to intense JS heap pressure, garbage collection stutters, and eventual MaxListenersExceeded or OOM crashes in Chromium's renderer process5.

1. A separate 1 MB SharedArrayBuffer (SAB) is established exclusively for IO messaging between the Main Thread and the Worker.

2. The SAB is partitioned into a Command Ring (UI [Figure omitted from source export] Worker) and an Event Ring (Worker [Figure omitted from source export] UI).

3. Prefill / Decode Command: The UI thread writes a bounded, typed command (e.g., \[OPCODE\_GENERATE, sequence\_length, prompt\_ptr\]) directly into the Command Ring and utilizes Atomics.notify() to wake the dormant worker thread.

4. Token Streaming: As the worker decodes tokens, it writes the integer token IDs directly into the Event Ring. The UI thread reads these at its own 60 frames-per-second rendering cadence via requestAnimationFrame. This architecture entirely decouples the inference loop (operating at \~15-30 tokens/sec) from the UI thread, ensuring zero duplicated DOM renders and absolute zero message queue bloat. Transfer and copy behaviors are explicit, manual, and bounded by the size of the ring buffer.

7. Cancellation, Poisoning, and Fresh-Worker Recovery

User-initiated cancellation must instantaneously terminate real hardware work. Relying on standard worker.terminate() as a primary cancellation mechanism is hostile; it halts the thread abruptly, potentially leaving OPFS locks held or SAB lock structures in undefined, deadlocked states48.

Cooperative Cancellation

The Command Ring within the SAB contains a dedicated atomic cancellation flag. Before executing the expensive matrix multiplication for each decoding step (or chunk of prefill), the WASM kernel executes an i32.atomic.load on this specific flag address. If the flag evaluates to 1, the kernel immediately aborts the current layer calculation, purges the KV cache of the partial sequence, resets its internal state machine, and safely returns to the READY state. This cooperative approach guarantees sub-millisecond cancellation latency without destroying the isolated worker environment.

Worker Poisoning and Containment

A worker is designated as permanently poisoned if any of the following occur:

1. A memory out-of-bounds error is caught by the WASM trap handler.

2. The main thread's Atomics.wait timeout indicates the WASM kernel is deadlocked.

3. A numerical NaN cascades through the RMSNorm layer, indicating corrupt floating-point state.

4. The OPFS file system throws a low-level synchronous IO error.

If poisoned, cooperative cancellation is abandoned. The main thread invokes worker.terminate(), forcefully discarding the worker, its WASM instance, and its compiled JIT cache to contain the failure.

Fresh-Worker Recovery

Upon respawning, a fresh worker must be capable of recovering the installed bytes. Because OPFS enforces strict file locking to prevent concurrent writes12, the abrupt termination of the previous poisoned worker releases the OS-level file lock automatically. The new worker instantiates a fresh 1.5 GB static WASM memory, executes the header-validation, and skips the full SHA-256 streaming hash (as the file was previously cryptographically sealed and verified during the initial installation). It maps the weights via a new FileSystemSyncAccessHandle.read() and is operational and ready for prompts within \~200 milliseconds.

8. Isolation Headers and Network Privacy Contract

To leverage SharedArrayBuffer for the ring-buffer protocol and Atomics-based cancellation, the web application must enforce strict Cross-Origin Isolation27.

Required HTTP Deployment Headers

The host server must deliver the foundational HTML document with the following strict HTTP headers to enable high-resolution timers and shared memory:

  • Cross-Origin-Opener-Policy: same-origin (COOP)
  • Cross-Origin-Embedder-Policy: require-corp (COEP)
  • Cross-Origin-Resource-Policy: same-origin (CORP)

Furthermore, to permit the V8 engine to compile the WASM binary (which requires the dynamic generation of executable machine code in the browser's memory cage), the Content Security Policy (CSP) must explicitly authorize WebAssembly without globally permitting insecure JavaScript eval()17. The mandatory CSP header is:

  • Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self';

Network Privacy Contract

TinyRustLM requires that model bytes remain strictly local or travel only via consenting peers50. There is an explicit zero-telemetry and zero-prompt-upload rule.

  • The CSP connect-src directive must be restricted exclusively to 'self' for initial WASM binary downloads, and webrtc:, stun:, or turn: endpoints for Peer-to-Peer data channels.
  • P2P Transfer: Model transfer between peers utilizes the WebRTC RTCDataChannel. Because a 598 MB file drastically exceeds datachannel underlying SCTP message limits, the worker must slice the OPFS file into strictly sized 16 KB chunks. The transfer loop must monitor the bufferedAmountLowThreshold to apply network backpressure. Sending data faster than the network can transmit queues the chunks in the browser's JS heap, which will rapidly lead to an OOM crash51.

9. Native/WASM Numerical Conformance

Native scalar C/Rust reference implementations and the WASM execution must prove exact numerical conformance. Language models are chaotic systems; minor floating-point drift in early layers exponentiates, causing the SLM2 outputs to diverge into hallucinations. Sources of Non-Determinism:

1. Associativity: WASM f32 addition is strictly IEEE-754 compliant. However, if the SIMD vector reduction trees differ in structure from the native scalar loops, floating-point rounding errors will accumulate differently. The native reference must perfectly mimic the exact binary tree reduction utilized in the WASM SIMD kernels.

2. Relaxed SIMD: As documented in the Wasm 3.0 specification20, relaxed\_dot intentionally leaves saturation behavior and NaN propagation implementation-defined to allow direct mapping to x86/ARM hardware.

3. Transcendental Functions: The browser's JIT provides Math.exp() and Math.log() (often invoked via WASM imports or compiled libc equivalents), which vary at the lowest bits between V8, SpiderMonkey, and JavaScriptCore due to different polynomial approximations.

Conformance Strategy: To gate a release, the WASM execution must demonstrate Token-Sequence Identity against the scalar reference given a fixed seed, a fixed prompt, and greedy decoding (Temperature \= 0.0). For Logit layers, an [Figure omitted from source export] norm error threshold of [Figure omitted from source export] is enforced. The Softmax implementation must use a custom, bit-exact Taylor series approximation for [Figure omitted from source export] compiled directly into the WASM binary, absolutely forbidding the use of the host browser's JavaScript Math.exp() to guarantee cross-browser numerical identity.

10. Performance and Resource Laboratory

Performance measurement relies on mathematically rigorous formulas and performance.now() high-resolution timestamps, strictly avoiding invented benchmarks.

Measurement Definitions

  • Cold Startup (Network): Time elapsed from the fetch() initiation of the 598 MB model to the completion of the WASM heap Uint8Array population and SHA-256 verification.
  • Warm Startup (OPFS): Time to execute FileSystemSyncAccessHandle.read() of the 598 MB model directly into WASM linear memory. Target: [Figure omitted from source export] on modern NVMe storage.
  • Compilation Latency: Time for WebAssembly.instantiateStreaming. Because V8 utilizes Liftoff for baseline tiering26, the promise resolves immediately upon stream completion, masking the background TurboFan CPU overhead.
  • Verification Latency: Time to execute crypto.subtle.digest("SHA-256") on 4MB chunks46. Target: \~800 MB/s hashing throughput on a dedicated worker thread.
  • First-Token Latency (Prefill): Time from the atomic command flag set in the SAB to the first token emitted to the Event Ring. Measured in Tokens/Sec, calculated as [Figure omitted from source export].
  • Decode Speed: Moving average of time between emitted tokens during autoregressive generation. Measured in Tokens/Sec.
  • KV Bytes/Token: Strictly formulated as [Figure omitted from source export] per layer, or [Figure omitted from source export] total per token across 24 layers.
  • Cancellation Latency: Time from UI thread writing 1 to the SAB cancellation flag to the worker writing STATUS\_READY to the Event Ring. Target: [Figure omitted from source export].
  • Recovery Time: Time to respawn a worker, re-read OPFS bytes, and reach STATUS\_READY. Target: [Figure omitted from source export].

Peak linear memory is continuously asserted to remain at the pre-allocated 1.5 GB static limit. Peak JS heap memory must be profiled via Chrome DevTools (performance.memory.usedJSHeapSize) to prove the ring-buffer implementation actively prevents garbage-collection pressure.

11. Cross-Browser and Fault-Injection Matrix

The target must support desktop and constrained environments, utilizing Chromium as the primary required proof.

Environment / FaultExpected BehaviorSupport Status
Chromium (Desktop, Win/Mac/Linux)Full 1.5GB static allocation, Relaxed SIMD hardware mapping, OPFS zero-copy.Proven (Baseline Requirement)
Firefox (Desktop)Fallback to SIMD128 if Relaxed SIMD hardware mapping differs. OPFS supported (v111+)23.Proven
WebKit (Safari Desktop v18+)OPFS supported24. Potential slower JIT compilation overhead.Blocked (Pending full WebKit OPFS sync validation)
Low-Memory Admission (Tab Suspension)If the OS triggers memory pressure, Chrome suspends background tabs56.The static 1.5 GB memory forces early eviction of other tabs, protecting the active TinyRustLM tab.
Background ThrottlingrequestAnimationFrame is throttled by the browser when the tab is hidden.Decoupled SAB ring-buffer continues to decode into memory even if the UI is throttled.
Browser Crash / Stale WorkerProcess termination destroys the worker.Restart triggers fresh-worker recovery (Section 7). OPFS remains intact.
Storage Quota LossOPFS eviction by browser disk-cleanup heuristics.Worker transitions to fatal state; initiates network re-download pipeline.

Note: Chromium on Android limits renderers significantly. Testing must enforce the 1.5 GB static memory allocation. If the Android Chromium OOM killer terminates the process due to hard memory ceilings48, the UI must gracefully downgrade to a smaller quantization or shorter context limit.

12. Acceptance Gate and Prioritized Implementation Plan

To qualify for release, the TinyRustLM execution must produce explicit objective evidence, strictly forbidding implicit fallbacks, silent retries, or hidden server reliance. Node execution is invalid as browser proof, as it lacks the COOP/COEP, CSP, and PartitionAlloc constraints of a live renderer process.

Release Evidence Gates:

1. Exact Browser Build: Chromium version [Figure omitted from source export] (64-bit OS).

2. Module Hash Identity: The SHA-256 hash of the compiled TinyRustLM.wasm binary and the 598 MB Qwen3 model must identically match the release manifest.

3. Numerical Gate: Given prompt byte-array [Figure omitted from source export] and seed [Figure omitted from source export], the generated token sequence [Figure omitted from source export] must perfectly match [Figure omitted from source export] for at least 500 consecutive decode steps.

4. Resource Ceilings:

  • WASM Linear Memory exactly 1.5 GB (zero memory.grow invocations detected in the runtime).
  • JS Heap average delta [Figure omitted from source export] during generation.

5. Network Trace: A recorded HAR (HTTP Archive) file demonstrating zero outbound bytes to non-P2P endpoints during the prompt generation phase.

Prioritized Implementation Plan:

1. Establish the OPFS synchronous loader and the WASM static linear memory sandbox.

2. Implement the SAB command/event ring-buffer and worker initialization sequence.

3. Compile the scalar-native reference into WASM. Prove deterministic numerical output against the reference.

4. Implement SIMD128 and Relaxed SIMD kernel hot-swapping for the Q8\_0 format.

5. Implement cooperative Atomics cancellation and poison-recovery logic.

13. Unknowns Requiring Local Real-Browser Execution

While the specification covers the mathematical bounds and theoretical execution models, certain Chromium behaviors require local laboratory execution to confirm:

1. V8 Pointer Compression Cage Fragmentation: Even with a statically allocated 1.5 GB WASM memory, V8's internal TurboFan compilation allocates massive structures on the native heap to build the sea-of-nodes IR42. It remains to be tested whether sustained heavy prompting causes V8 to fragment its own 4 GB sandbox6, leading to an internal OOM independent of the WASM linear memory.

2. OS-Level Page Faulting: The OPFS FileSystemSyncAccessHandle reads data into memory. The OS virtual memory manager dictates when these pages are actually backed by physical RAM. The latency jitter caused by OS-level page faults during the initial attention prefill phase must be measured on constrained hardware.

3. Relaxed SIMD Micro-architecture Variations: The exact mapping of relaxed\_dot\_i8x16\_i7x16\_add\_s on specific AMD vs. Intel vs. Apple Silicon micro-architectures may yield varying NaN handling behaviors that only emerge under heavy temperature-scaled sampling.

14. Annotated Primary-Source Bibliography with Dates

  • \[1, 9\] BaseWatch / CanIUse (2025/2026): Documentation on WebAssembly Memory64 adoption. Confirms Chrome 133+, Firefox 134+, and Edge 150+ full support, while Safari lags in Technology Preview.
  • \[5, 7, 12\] SciChart Memory64 Analysis (2025/2026): Evaluates the 10% performance hit inherent in 64-bit WASM pointers due to bounds checking overhead, justifying the retention of WASM32 for SLMs under 2 GB.
  • \[39, 44, 45\] Wasm 3.0 Relaxed SIMD Specification (2024-07-10): WG approval of relaxed SIMD. Confirms the introduction of relaxed\_dot\_i8x16\_i7x16\_s and details the trade-off of strict determinism for hardware-native FMA capabilities.
  • \[46, 54, 294, 298, 301\] Qwen2.5-0.5B Architecture Configurations (2024): Specifies the structural hyperparameters (896 hidden size, 24 layers, 14 attention heads, 2 KV heads, 151,936 vocab size) crucial for calculating exact peak memory and KV cache boundaries.
  • \[68, 71, 74, 79\] OPFS Deep Dive (2023/2024): Details FileSystemSyncAccessHandle for synchronous, zero-copy data reads in Web Workers, critical for bypassing JS heap bloat.
  • \[83, 85, 87, 88\] GGML Q8\_0 Quantization Format (2024): Defines the 34-byte block structure (32 int8 weights \+ 1 fp16 scale), yielding 8.5 bits per weight, required to calculate the exact 598 MB payload size.
  • \[104, 113\] Deno / WebCrypto Streaming Hash (2024): Demonstrates the use of crypto.subtle.digest("SHA-256", stream) to validate large files incrementally without buffering them into RAM, essential for model verification.
  • \[132, 135, 245, 278\] Chromium V8 Sandbox and OOM (2022-2024): Technical breakdowns of V8's 4 GB pointer compression cage. Establishes the fatal risks of dynamic memory growth and JS heap accumulation leading to renderer process termination (exit code \-536870904).
  • \[154, 157, 160, 204\] V8 WASM Memory Re-allocation Vulnerabilities (2024): Details how memory.grow() forces V8's PartitionAlloc to reallocate backing stores, leading to stale JIT pointers and sandbox escapes, cementing the requirement for a static initial \== maximum memory configuration.
  • \[177, 182, 184, 219\] WASM Compilation Overheads (2019-2024): Explains the V8 multi-tier compilation process (Liftoff and TurboFan). Highlights the severe memory and CPU overhead of instantiating multiple WASM workers simultaneously, validating the single-worker topology.
  • \[191, 194, 197, 216\] WebRTC DataChannel (2021-2023): Outlines the 16KB chunking requirements and bufferedAmountLowThreshold limits to prevent backpressure bloat during P2P transfers.
  • \[233, 237, 241\] W3C Content Security Policy Level 3 (2021-2024): Defines the integration of wasm-unsafe-eval within the script-src directive, required to permit WebAssembly compilation in isolated web contexts.

Works cited

1. Is Memory64 actually worth using? \- SpiderMonkey, https://spidermonkey.dev/blog/2025/01/15/is-memory64-actually-worth-using.html

2. Memory64: Unlocking WebAssembly's True Potential with 16GB of, https://www.scichart.com/blog/memory64-unlocking-webassemblys-true-potential-with-16gb-of-in-browser-memory/

3. Wasm 3.0 Completed \- WebAssembly, https://webassembly.org/news/2025-09-17-wasm-3.0/

4. Memory64 in 2026: Breaking the 4GB Ceiling in Browsers and Servers, https://wasmhub.dev/blog/memory64-in-2026

5. VS Code extension: Renderer OOM crash (code \-536870904) and, https://github.com/anthropics/claude-code/issues/35968

6. Electron and the V8 Memory Cage, https://electronjs.org/blog/v8-memory-cage

7. hack-skills/skills/browser-exploitation-v8/SKILL.md at main \- GitHub, https://github.com/yaklang/hack-skills/blob/main/skills/browser-exploitation-v8/SKILL.md

8. V8 WebAssembly Memory Re-allocation Bypass of JIT-Optimized, https://issues.chromium.org/issues/447032777

9. Wasm needs a better memory management story \#1397 \- GitHub, https://github.com/WebAssembly/design/issues/1397

10. Efficient And Safe Allocations Everywhere\! \- Chromium Blog, https://blog.chromium.org/2021/04/efficient-and-safe-allocations-everywhere.html

11. Fixing the Cypress out of memory error in Chromium \- BigBinary, https://www.bigbinary.com/blog/how-we-fixed-the-cypress-out-of-memory-error-in-chromium-browsers

12. File System Standard, https://fs.spec.whatwg.org/

13. WebKit Features in Safari 16.4, https://webkit.org/blog/13966/webkit-features-in-safari-16-4/

14. OPFS: The Origin Private File System \- Web Storage \- Apurv Khare, http://apurvkhare.com/articles/frontend/web-storage/opfs

15. WASM Guide \- The halo2 Book \- Zcash, https://zcash.github.io/halo2/user/wasm-port.html

16. Memory64 (WebAssembly) | Can I use... Support tables for HTML5, https://caniuse.com/wf-wasm-memory64

17. The State of WebAssembly – 2025 and 2026 \- Uno Platform, https://platform.uno/blog/the-state-of-webassembly-2025-2026/

18. Memory64 (WebAssembly) browser support at 68.8% \- BaseWatch, https://basewatch.dev/feature/wf-wasm-memory64

19. Globals | The AssemblyScript Book, https://www.assemblyscript.org/stdlib/globals.html

20. \[API Proposal\]: System.Runtime.Intrinsics.Wasm.RelaxedSimd, https://github.com/dotnet/runtime/issues/130223

21. WebAssembly Specification \- Ng Zhi An, https://www.ngzhian.com/relaxed-simd/core/\_download/WebAssembly.pdf

22. Rounding semantics for i32x4.relaxed\_dot\_i8x16\_i7x16\_add\_s \#129, https://github.com/WebAssembly/relaxed-simd/issues/129

23. File System API \- MDN Web Docs, https://developer.mozilla.org/en-US/docs/Web/API/File\_System\_API

24. SQLite Wasm for Safari And Firefox progress, https://sqlite.org/forum/forumpost/449ae66eb1

25. Worker Deployment \- Ruby2JS, https://www.ruby2js.com/docs/juntos/deploying/worker

26. WebAssembly Integration | FrontendPro, https://frontendpro.study/articles/js-enginelevel-webassembly-integration

27. WebAssembly in Workers, https://javascript-web-workers.com/high-performance-computation-patterns/webassembly-in-workers/

28. Writing your first WebAssembly module using C (C++) | by ... \- Medium, https://medium.com/jspoint/the-anatomy-of-webassembly-writing-your-first-webassembly-module-using-c-c-d9ee18f7ac9b

29. Content-Security-Policy (CSP) header \- HTTP \- MDN Web Docs, https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Content-Security-Policy

30. Isolated Contexts \- GitHub Pages, https://wicg.github.io/isolated-web-apps/isolated-contexts.html

31. Fine-grained Wasm execution policies · Issue \#37 \- GitHub, https://github.com/WebAssembly/content-security-policy/issues/37

32. Qwen2 \- Hugging Face, https://huggingface.co/docs/transformers/model\_doc/qwen2

33. config.json · Qwen/Qwen2.5-0.5B-Instruct at main \- Hugging Face, https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct/blame/main/config.json

34. config.json · Qwen/Qwen2.5-0.5B at, https://huggingface.co/Qwen/Qwen2.5-0.5B/blob/060db6499f32faf8b98477b0a26969ef7d8b9987/config.json

35. CCI3.0-HQ: a large-scale Chinese dataset of high quality ... \- arXiv, https://arxiv.org/html/2410.18505v2

36. 以Qwen 为例,学习大模型的结构 \- 陈少文的网站, https://www.chenshaowen.com/blog/structure-of-large-models-with-qwen.html

37. GGUF quantization, bit by bit \- dwarez, https://dwarez.dev/blog/gguf-quantization-bit-by-bit

38. m1el/nemotron-speech-streaming-0.6B-gguf \- Hugging Face, https://huggingface.co/m1el/nemotron-speech-streaming-0.6B-gguf

39. A system programmer's guide to LLM inference \- Xiangpeng's blog, https://blog.xiangpeng.systems/posts/how-to-llm-inference/

40. Compilation Performance and Shared Code Caching in Node.js, https://www.researchgate.net/publication/348810322\_Insights\_into\_WebAssembly\_Compilation\_Performance\_and\_Shared\_Code\_Caching\_in\_Nodejs

41. WebAssembly compiled module cache · Issue \#36671 · nodejs/node, https://github.com/nodejs/node/issues/36671

42. A Little on V8 and WebAssembly \- PLISS 2019, https://pliss2019.github.io/ben\_titzer\_webassembly\_slides.pdf

43. The origin private file system | Articles \- web.dev, https://web.dev/articles/origin-private-file-system

44. absurder-sql \- SQLite User Forum, https://sqlite.org/forum/info/9ff8428886217d0b

45. File System Access API: Browser Support, Methods, Limits \- TestMu AI, https://www.testmuai.com/learning-hub/file-system-access-api-browser-support/

46. SubtleCrypto: digest() method \- Web APIs | MDN, https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest

47. Hash large files with streams \- Deno Docs, https://docs.deno.com/examples/hash\_file\_streams/

48. Chrome OS Out of Memory Design \- The Chromium Projects, https://www.chromium.org/chromium-os/chromiumos-design-docs/out-of-memory-handling/

49. DallasHoff/sqlocal \- Allow using sqlite's OPFS\_SAH backend \- GitHub, https://github.com/DallasHoff/sqlocal/issues/39

50. Add support for WebRTC Data Channel in Workers \#230 \- GitHub, https://github.com/w3c/webrtc-pc/issues/230

51. RTCDataChannel: bufferedAmountLowThreshold property \- Web APIs, https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/bufferedAmountLowThreshold

52. WebRTC and Buffers \- GetStream.io, https://getstream.io/resources/projects/webrtc/advanced/buffers/

53. WebRTC Datachannel for high bandwidth application \- Stack Overflow, https://stackoverflow.com/questions/56327783/webrtc-datachannel-for-high-bandwidth-application

54. Webrtc datachannel.send() call stalls briefly when a large amount of, https://groups.google.com/g/discuss-webrtc/c/EjevtDTsxuE

55. Origin private file system \- Web APIs | MDN, https://developer.mozilla.org/en-US/docs/Web/API/File\_System\_API/Origin\_private\_file\_system

56. FIX Chrome Out of Memory Errors: 5 Fixes Ranked (2026), https://www.superchargebrowser.com/library/fix-chrome-out-of-memory/