惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Google DeepMind News
Google DeepMind News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
宝玉的分享
宝玉的分享
量子位
博客园 - 叶小钗
博客园_首页
Know Your Adversary
Know Your Adversary
S
Schneier on Security
罗磊的独立博客
C
Cyber Attacks, Cyber Crime and Cyber Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Simon Willison's Weblog
Simon Willison's Weblog
美团技术团队
WordPress大学
WordPress大学
大猫的无限游戏
大猫的无限游戏
Hacker News: Ask HN
Hacker News: Ask HN
Application and Cybersecurity Blog
Application and Cybersecurity Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Security Latest
Security Latest
月光博客
月光博客
Spread Privacy
Spread Privacy
C
Cybersecurity and Infrastructure Security Agency CISA
人人都是产品经理
人人都是产品经理
J
Java Code Geeks
C
CERT Recently Published Vulnerability Notes
Last Week in AI
Last Week in AI
Attack and Defense Labs
Attack and Defense Labs
NISL@THU
NISL@THU
H
Hacker News: Front Page
N
News and Events Feed by Topic
小众软件
小众软件
T
Threatpost
V2EX - 技术
V2EX - 技术
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
Project Zero
Project Zero
L
LINUX DO - 热门话题
Apple Machine Learning Research
Apple Machine Learning Research
C
CXSECURITY Database RSS Feed - CXSecurity.com
TaoSecurity Blog
TaoSecurity Blog
P
Privacy International News Feed
Latest news
Latest news
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
酷 壳 – CoolShell
酷 壳 – CoolShell
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AWS News Blog
AWS News Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 【当耐特】
Hugging Face - Blog
Hugging Face - Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Sipp: a local-first runtime for Hybrid AI Applications
Constant, Yuan Chen · 2026-06-24 · via DEV Community

Over the past few months, I had the opportunity to contribute to llama.cpp’s WebGPU backend, helping push it from isolated operator support toward a more complete and reliable path for browser-based and multimodal inference. It was a collective effort with dozens of contributors, and was an essential component of getting Sipp ready for release. The lead maintainer, Reese Levine, wrote a really nice blog post about it, Llamas on the Web, and published a paper around the architecture design. In this tech post, I want to share some thoughts into the WebGPU in-browser inference, and the larger ecosystem we are building to unify both local and cloud compute in a hybrid inference design for making intelligence more available.

What it means to make intelligence available

A technology becomes interesting when it works in a lab, and becomes transformative when people can actually reach it, run it, adapt it, and build with it in the environments they already use. That is the sense in which Sipp is about making AI more available.

Language models have mostly entered software through chatboxes, but interactive applications rarely begin with a complete prompt. In games, design tools, and agent workspaces, the useful context is often the live environment itself: the open document, selected objects, recent edits, user actions, scene state, and background work. As open models become smaller and more capable, more of that work can happen close to the user. This matters for more than speed and privacy. Useful contexts should not require every interaction to cross a cloud boundary, depend on frontier-model pricing, or be gated by a single provider. Frontier models are
still better for deep reasoning, and planning, but most interactive software does not need that depth at every step. The stronger design is a split one: local models for immediate, private, continuous interaction, and larger remote models when the task truly requires deeper reasoning.

Sipp is designed for the space between them. You can register a local model, a gateway target, or a provider endpoint, and then call the same operations against the selected endpoint. In this remaining sections, I will introduce the system design behind Sipp, including:

  • how Sipp represents local, gateway, and provider endpoints
  • why query, chat, and embed are separate operations
  • how the local engine schedules requests and reuses key-value (KV) cache state
  • how the browser host makes WebGPU practical for GGUF models
  • how the gateway provides a policy and operations boundary for remote compute

Architecture at a glance

Sipp uses endpoint registration. An endpoint can run in the same process, in the browser, behind an HTTP gateway, or at an external provider. The application keeps the endpoint reference and passes it to query, chat, or embed.

flowchart LR
  App[Application] --> Client[SippClient]
  Client --> Local[Local endpoint]
  Client --> Gateway[Gateway endpoint]
  Client --> Provider[Provider endpoint]

  Local --> Engine[Sipp Engine]
  Engine --> Native[llama.cpp and ggml]

  Gateway --> GatewayServer[Gateway server]
  GatewayServer --> ServerClient[SippClient]
  ServerClient --> ServerLocal[Server local model]
  ServerClient --> ServerProvider[Provider target]

The diagram shows two important properties. First, the application chooses the endpoint. Sipp does not silently move a request from a local model to a remote model. The application owns the product
constraints, such as privacy, cost, latency, and quality. Second, the operation shape stays stable. A feature can start with a browser model, add a server-side local model later, and then add a gateway target for harder requests without changing the public operation model.

Endpoint model

The core client stores endpoints behind a common inference endpoint interface. SippClient::add() builds the endpoint from a descriptor:

  • A local model descriptor loads SippEngine.
  • A gateway descriptor builds an HTTP gateway endpoint.
  • A provider descriptor builds a direct provider adapter when provider support is enabled.

After registration, Sipp resolves operations to the selected endpoint, check whether it supports
the requested operation, and return the same run and response types. This design keeps endpoint selection explicit while keeping the application API small.

Request operations

Sipp separates query, chat, and embed because each operation has different
runtime requirements.

query sends a raw prompt string, without applying a chat template. Use this
operation when the application owns the prompt format, such as completion-style
prompts, few-shot prompts, custom templates, encoder-decoder flows, or agent
loops that render prompts themselves.

chat sends ordered role and content messages. A local endpoint applies the
model's chat template. A gateway or provider endpoint maps those messages into
the selected remote protocol.

embed returns vectors instead of generated text. The endpoint must support
embeddings, and the local runtime uses a different path because it reads an
embedding result instead of sampling output tokens.

The separation prevents common integration bugs. A raw prompt does not
accidentally become a chat transcript. A chat request is not sent to a local
model without the model's template. An embedding request is not routed to a
generation-only endpoint.

The gateway and provider paths also enforce this boundary. Gateway requests
reject local-only fields such as contextKey, grammar, and local sampling overrides. Endpoint-specific options must be JSON-compatible and cannot override typed fields such as model, prompt, messages, or stream.

Local engine

The local engine is the part of Sipp that turns endpoint calls into interactive
inference work.

The core loop is tick-based. A request enters the runtime, becomes an internal
generation or embedding request, and advances through scheduler ticks. This
model fits interactive applications, where a visible chat response, a short
background classification, and a longer prefill can overlap.

At each tick, the engine separates prompt prefill from token decode. The batch
planner builds a flat list of token contributions from ready slots. Each
contribution is either Prefill or Decode, and includes the slot index,
request ID, token, position, and whether the request needs logits.

This split gives the scheduler direct control over latency and throughput:

  • Decode steps are latency-sensitive because they produce visible tokens.
  • Prefill steps can process many prompt tokens before the first generated token.
  • Active decode streams should not wait behind a long prompt.
  • Long prompts should still make progress while decode streams are active.

The planner budgets decode and prefill separately. Reusing the plan
avoids repeated allocation in the scheduler hot path. The planner also uses a
small bitmask fast path for counting occupied slots instead of allocating a
HashSet on each tick.

After the native backend runs, Sipp applies request bookkeeping and emits token
batches. The runtime records the request metrics for observability.

Key-value cache as runtime state

Each local request can carry a contextKey. The key represents the logical
workflow, such as a document, scene, conversation, workspace, or
background task. The engine uses that key to decide whether it can reuse live KV
state or restore a prefix snapshot.

The KvCacheManager maps context keys to physical sequence slots. When a request completes and cache reuse is enabled, Sipp can keep the sequence idle but resident. A later request with the same contextKey can use that warm state. If the runtime has more active contexts than physical sequences, it evicts idle sessions with an LRU policy. Sipp also supports prefix snapshots. During prefill, the runtime can restore the best matching snapshot for the same model fingerprint and context scope. It then recomputes only the missing suffix. The prefill path computes longest common prefix reuse, checks whether partial KV reuse is valid for the model family, makes room in the context window, and records cache hits.

This cache state matters for hybrid routing because it presents the cost of
asking for local evidence. A warm contextKey can let the runtime reuse prefix
tokens, run a short verifier, or draft an answer without paying full prefill
cost again. A router can then decide whether to return the local result, send
the draft to the gateway for audit, or skip local work when the task likely needs a stronger model. For example, an editor can use the same contextKey while a user works inside
one file. The first request pays the cost of reading the file and recent edits into the local model. A follow-up request, such as "is this edit safe?", can reuse that warm prefix and run a cheap local check. If the check is confident, the UI can respond immediately. If the check is uncertain or the check needs more contexts, the router can send the task to the gateway instead.

Instead of a static local-then-cloud cascade, a route can use cache hits, prefill cost, network latency, and provider cost as routing inputs. We are currently researching in this area and hopefully we can bring some insights to this topic in the future.

Browser host

The browser host owns packaging, model staging, capability selection, and the JavaScript-facing runtime API. It does not duplicate the inference engine in the Rust core.

The build compiles the Rust browser ABI as an Emscripten static library. It then
links that library with llama.cpp, ggml, ggml-webgpu, and the multimodal
runtime. The ggml-webgpu target embeds WGSL shader files into a generated
header, and the Emscripten build uses Dawn's emdawnwebgpu port to call browser
WebGPU from C++ and WebAssembly.

The browser client runs through a worker-backed model service or a
main-thread model service and ships single-thread and pthread WebAssembly
artifacts. The pthread artifact requires SharedArrayBuffer, cross-origin
isolation, and the deployment headers that enable shared memory. The
single-thread artifact remains available when those requirements are not met.

Backend selection is capability-aware:

  • If the app requests CPU, Sipp uses CPU.
  • If the app requests WebGPU, Sipp returns adapter information.
  • If the app uses automatic selection, Sipp selects WebGPU only when the adapter exposes shader-f16; otherwise, it falls back to CPU.

Model loading is part of inference performance. The browser cache policy loads
files directly up to 2 GiB. It splits larger GGUF assets into 512 MiB shards and
loads those shards automatically. For large assets, the browser package stores
the files in OPFS, opens sync access handles, and mounts those handles into
Emscripten's filesystem. Read calls copy bytes from OPFS directly into a
Uint8Array view of the WebAssembly heap. That avoids reading into a JavaScript
ArrayBuffer and then copying the same bytes again into HEAPU8. Vision models use the same lifecycle. The main model weights can be staged as GGUF shards, while the projector artifact is staged separately for the multimodal runtime.

WebGPU case study

The main difference of the WebGPU backend from ONNX and TVM/WebLLM is the representation.
ONNX treats WebGPU as an execution provider for ONNX graphs. That is
a good fit for portable graph artifacts and provider abstraction. The tradeoff
is that GGUF-native details, such as tokenizer metadata, chat templates, KV
behavior, and llama.cpp quantized layouts, must cross a different artifact
boundary. TVM/WebLLM uses a compiler pipeline. Model computation is lowered through
MLC-LLM and Apache TVM into WebGPU and WebAssembly
artifacts. That path can apply ahead-of-time optimization, graph fusion, and
operator scheduling for a curated model catalog. The tradeoff is that users do
not point the runtime at an arbitrary GGUF file and run it directly.

GGML WebGPU keeps the model format and runtime behavior closer to execution.
ggml still builds the tensor graph dynamically, and WebGPU executes that graph
in the browser. The backend maps tensor views to WebGPU buffer offsets, supports
quantized layouts without expanding them into large intermediate tensors,
specializes shader pipelines by tensor type and quantization format, and reuses
per-kernel parameter storage. For quantized matrix multiplication,
dequantization stays in the shader path instead of becoming a separate
model-conversion step.

That architecture fits decode-heavy workloads. Decode often depends on memory
bandwidth because each generated token streams weights and attends over KV
state. Keeping quantized weights close to execution reduces memory expansion and
copy costs. Prefill has different tradeoffs because it exposes more parallelism
and can benefit from compiler fusion.

Through our public browser benchmark tooling at
benchmark.sipp.sh/benchmark, we achieved
the following results with an NVIDIA GTX 3080, one warmup run, and three
measured runs:

Runtime or framework Time to first token, lower is better Decode, higher is better End-to-end latency, lower is better
Sipp browser runtime 24.3 ms 77.07 tok/s 6,655 ms
WebLLM 160.0 ms 25.80 tok/s 19,930 ms
Transformers.js 301.0 ms 33.25 tok/s 15,670 ms

This benchmark is one data point. Browser version, model, memory pressure and other factors can change results, but these numbers are still useful because they match the architecture: fewer avoidable copies, GGUF-native execution, and quantized decode in the backend.

Gateway control plane

Sipp separates gateway responsibilities into layers:

  • sipp::gateway_core defines protocol-neutral operations, request context, cancellation, stream events, target resolution, authorization, admission, and execution traits.
  • lib/gateway provides route-free HTTP helpers, including codecs, authentication traits, error translation, JSON responses, and server-sent events (SSE) encoding.
  • apps/gateway-server is the Axum application. It owns TOML configuration, listeners, bearer tokens, CORS, request-size limits, concurrency limits, rate limiting, metrics, and the admin dashboard.

This separation keeps policy out of the local engine. A product can hide
provider secrets, restrict targets by caller, enforce request-size limits, rate
limit public clients, expose health routes, or run a local model on a server GPU
without changing the local runtime.

The gateway server loads configured targets into a SippClient and
stores a map from public target names to endpoint references. Incoming requests
resolve a target, check authorization, acquire admission, and then execute the
same query, chat, or embed operation through SippClient.

Query and chat can return finite responses or streams. Streaming responses use
SSE events: token batches, optional usage, and a final done event with finish
metadata. Embeddings use a finite response path.

The browser gateway client mirrors that contract. It validates the gateway base
URL, allows HTTP only for loopback, supports bearer and header authentication
with value providers, redacts secrets from errors, bounds error bodies and SSE
event sizes, and parses token, usage, done, and error events into the same
browser run abstraction used by local inference.

Hybrid routing

Hybrid routing is under active research, and the decision depends on runtime
signals, including:

  • local model latency for the current device and backend
  • privacy requirements for the task
  • expected reasoning depth
  • remote target availability, cost, and authorization

With those signals, an application can start with simple policies:

  • Keep UI classification, lightweight summarization, grammar-constrained extraction, scene synchronization, and private state-adjacent tasks local.
  • Delegate long-horizon planning, difficult synthesis, stronger world knowledge, or high-accuracy tasks to a gateway target.
  • Send the remote model only the context it needs.

The application still owns the routing decision. Sipp provides the common
runtime model that makes the decision practical.

Closing

At the start of Sipp, the motivation was simple: AI should be usable in more places than a remote chatbox. By the end, that had become a systems question: how do we make model compute available inside real applications, close to the user when interaction demands it, and connected to deeper reasoning when the task requires it? That is the vision Sipp is built to support.

During this journey, I learned a lot by working close to inference itself and to the llama.cpp community. My work covered backend stability, shader correctness and optimization, quantized-kernel behavior, and the operator coverage needed by vision models. A challenge along the way was tracing precision drift through the CLIP vision path, attention shaders, and feed-forward layers, then fixing the shader behavior until multimodal outputs matched the CPU reference much more closely. This was not just implementation work, but required some low-level debugging across WGSL shaders, memory semantics, quantization formats, and real model validation. These contributions became a central part of making llama.cpp’s WebGPU support more stable, complete, and practically usable. The deeper lessons, however, were not only technical. They came from seeing how much careful work sits behind a model that feels simple to use, and from collaborating with people who were solving the same problems from different parts of the stack.

Looking forward, Local models handle the work that benefits from being close to the user. Cloud models are available when a task needs more depth. Applications should not have to choose one side forever. They should be able to place computation where it makes the experience better. This brings the argument back to where it started: the future is not just better chatboxes, but environment-aware software that can act close to the user and reason deeply when needed. Sipp is built to make that practical.