qvac

tethertoApache-2.0活跃维护

开源本地 AI SDK,无需云端和 API Key 即可在设备端跑 GGUF 模型,集成 RAG、图像音乐视频生成、语音转写和 P2P 推理,覆盖桌面与移动端。

Open-source local AI SDK - run AI on-device with no cloud, no API keys. Supports GGUF, RAG, image, music, and video generation, speech-to-text, P2P inference, and more. Cross-platform: Linux, macOS, Windows, Android, iOS.

sdk-v0.23.0发布于 2026-11-02 12:57 UTC759star +8 / 7 天156fork同步于 2026-11-10 11:56 UTC

怎么上手

由 README 提炼,执行前请确认
npm i @qvac/sdk
pip install tetherto-qvac-sdk -f https://github.com/tetherto/qvac/releases/expanded_assets/sdk-v<version>
npm install -g @qvac/cli
硬件要求按 README 说明

README 未给出具体显存或 GPU 型号要求,仅说明针对消费级硬件与嵌入式系统优化,并覆盖 Linux、macOS、Windows、Android、iOS;部分能力(如音乐生成)标注为桌面端。

需要 CUDA
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

开源本地 AI SDK,无需云端和 API Key,在设备端跑 LLM、语音、视觉与生成模型

开源本地 AI SDK,无需云端和 API Key 即可在设备端跑 GGUF 模型,集成 RAG、图像音乐视频生成、语音转写和 P2P 推理,覆盖桌面与移动端。

核心能力

  • 提供 JS/TS 与 Python SDK 统一调用多种本地 AI 能力
  • 内置 OpenAI 兼容 HTTP 服务,可接入 OpenCode 等工具
  • 支持 GGUF 模型加载与流式 token 输出
  • 覆盖文本、嵌入、RAG、LoRA 微调与多模态推理
  • 支持图像、视频、音乐生成及语音转写与合成

容易踩的坑

首次运行会先下载模型,需保证网络与磁盘空间;Python 包安装需把 替换为实际发布版本并指定 releases 源;HTTP 服务默认绑定 127.0.0.1:11434,需在配置中声明要 serve 的模型。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本sdk-v0.23.0
  1. sdk-v0.23.0QVAC SDK v0.23.0最新正式版2026-11-02 · 2026-11-02 12:57 UTC

    📦 NPM: https://www.npmjs.com/package/@qvac/sdk/v/0.23.0

    QVAC SDK 0.23.0 sits on @qvac/[email protected]. It adds reranking with rerank() and a llamacpp-rerank model type, speculative decoding, prompt priming with prefill, finer prompt-cache control, TranscribePsy transcription, and Qwen-Image-2.1 generation and reference editing. Native addons move onto fabric 0.24, which changes the RPC protocol to 112, and bundling moves to bare-pack 3. The model fit runs inside the worker on every platform, and completions now allow parallel tool calls by default. The Python client gains assess_model_fit and model_fit_policy wrappers and pins bare-rpc below 0.1. A new Kotlin client brings the SDK to Android apps; this release ships it as Maven archives attached below (see Kotlin client).

    It depends on @qvac/inference ^0.23.0, and tetherto-qvac-sdk and the Kotlin client publish at the same version.

    Table of Contents

    Kotlin client

    New from 0.23.0: io.tether:qvac-sdk-kotlin, a Kotlin client that drives the same worker as the JS/TS and Python clients.

    • Use it for: on-device AI in Android apps (arm64-v8a, API 29+). Desktop JVM is experimental.
    • What's different: Kotlin data classes and coroutine Flow streams, with a self-contained runtime hosted in an isolated Android service.
    • Install: At the moment, using the QVAC Kotlin SDK is possible via the Maven repository archive for your runtime profile from this release's assets and pointing Gradle at it.
    • Learn more: Kotlin SDK docs

    Breaking Changes

    Fabric 0.24 addon set

    The SDK now ships the fabric 0.24 addon set. It installs these addons itself; an app that also pins any of them must move to the same floor:

    Package0.22.0 floor0.23.0 floor
    @qvac/inference^0.22.0^0.23.0
    @qvac/asr-ggml^0.10.0^0.11.1
    @qvac/audiogen-ggml^0.8.0^0.9.0
    @qvac/bci-whispercpp
  2. sdk-v0.22.0QVAC SDK v0.22.02026-10-19 · 2026-10-19 11:31 UTC
    查看更新说明

    📦 NPM: https://www.npmjs.com/package/@qvac/sdk/v/0.22.0

    QVAC SDK 0.22.0 sits on @qvac/[email protected]. assessModelFit now asks each engine's fitter instead of a shared coefficient table, a load can set modelFitPolicy for itself, and completions can issue parallel tool calls with nested JSON Schema still intact. MiniMax-H3 can start a video from a still, decide() answers typed Laya questions, and the catalog adds MOSS speech, Laya decisions, and Nemotron diarization. Native addons move onto fabric 0.22. Bundling needs Node ^22.21.0 || >=24.9.0.

    The committed range is ^0.22.0. tetherto-qvac-sdk publishes at the same version.

    Table of Contents

    Breaking Changes

    Node version for qvac bundle / bare-pack

    bare-pack needs Node ^22.21.0 || >=24.9.0. Earlier 22.x (including 22.20.0) crashes the lexer. qvac doctor and qvac bundle sdk refuse those versions instead of native-crashing.

    Before:

    "engines": { "node": ">=18.0.0" }
    

    After:

    "engines": { "node": "^22.21.0 || >=24.9.0" }
    

    assessModelFit uses engine fitters

    Every candidate is assessed by the engine that would run it. The 'calibration' evidence class is gone, and so is estimate on the result and on each model. Under 'computed-only', floorBytes is the bound. A candidate the engine itself calls a fit can still come back likely-too-large: the interactive-v1 reserve applies on top of the engine's own headroom.

    Before:

    const result = await assessModelFit({ models })
    result.evidence // 'calibration' | 'computed-only' | 'native-fit'
    result.estimate // { lowerBoundBytes, upperBoundBytes }
    result.models[0].estimate // same
    

    After:

    const result = await assessModelFit({ models })
    result.evidence // 'computed-only' | 'native-fit'
    result.floorBytes // bound under 'computed-only'
    

    Per-load modelFitPolicy

    Skipping the fit probe was process-wide (QVAC_ADVISORY_MODEL_FIT=0) and also disabled the engine verdict for assessModelFit. The probe is now per load. 'log' (default) still runs it and never blocks. 'off' skips it for that load only. 'refuse' fails a load the engine projects will not fit.

    Before:

    // Skipping the fit probe was process-wide, and also disa
    
  3. sdk-v0.21.1QVAC SDK v0.21.12026-10-16 · 2026-10-16 16:55 UTC
    查看更新说明

    📦 NPM: https://www.npmjs.com/package/@qvac/sdk/v/0.21.1

    Update native add-ons to include the latest fixes and allow compatible patch updates.

    Update your app lockfile and rebuild native bundles to apply the fixes.

  4. sdk-v0.21.0QVAC SDK v0.21.02026-10-04 · 2026-10-04 16:06 UTC
    查看更新说明

    📦 NPM: https://www.npmjs.com/package/@qvac/sdk/v/0.21.0

    QVAC SDK 0.21.0 sits on @qvac/[email protected]. A model can split across machines through llama.cpp's RPC backend, Ternary Bonsai 2 27B runs in QVAC's engine, tools can defer their schemas behind tool_search, and TTS/ASR pick up MOSS plus Parakeet Core ML on Apple. Mobile bundles can auto-install addon platform packages, and verifyBundle checks engines.bare against the Bare runtime each host actually runs. Catalog constant names for BitNet, Llama tool-calling, and Indic Parakeet change. assessModelFit now takes loadModel fields instead of a separate workload object, infers modelType from modelSrc when omitted, and the load-time fit probe runs on every engine that ships a fitter.

    The committed range is ^0.21.0. tetherto-qvac-sdk publishes at the same version.

    Table of Contents

    Breaking Changes

    assessModelFit uses loadModel parameters

    Candidates are described the same way as a load: modelSrc, modelType, and modelConfig. The old model / workload / artifacts object is rejected.

    Before:

    await assessModelFit({
      models: [
        {
          model: LLAMA_3_2_1B,
          workload: { kind: 'llm', contextTokens: 4096 },
          artifacts: [MMPROJ_F16]
        }
      ]
    })
    

    After:

    await assessModelFit({
      models: [
        {
          modelSrc: LLAMA_3_2_1B,
          modelType: 'llamacpp-completion',
          modelConfig: { ctx_size: 4096, projectionModelSrc: MMPROJ_F16 }
        }
      ]
    })
    

    modelType is optional and inferred from modelSrc when omitted, the same way loadModel infers it. Required only where the source names no engine. A load whose sources are all config fields may omit modelSrc. Audio workload.windowMs becomes modelConfig.duration_ms. workload.batch has no equivalent and is gone.

    Flattened fit-probe projection

    getLoadedModelInfo().fitProbe.projection is a flat byte breakdown. projection.devices and NativeProbeDevice are gone. Totals are summed across devices; deviceName names the first.

    Before:

    info.fitProbe?.projection?.devices
    

    After:

    info.fitProbe?.projection?.deviceBytes
    info.fitProbe?.projection?.hostBytes
    info.fitProbe?.projection?.weightsBytes
    info.fitProbe?.projection?.contextBytes
    info.fitProbe?.projection?.computeBytes
    info.fitProbe?.projection?.deviceName
    

    Catalog constant names

    BitNet instructed TQ2_0 exports are retagged as base. Llama tool-calling 1B moves from Q4_K to Q4_K_M. Indic Parakeet Conformer CTC constants are replaced by the 600M GGUFs.

    Before:

    import { BITNET_0_7B_INST_TQ2_0 } from '@qvac/sdk'
    import { LLAMA_TOOL_CALLING_1B_INST_Q4_K } from '@qvac/sdk'
    import { PARAKEET_INDIC_CONFORMER_CTC_Q4_0 } from '@qvac/sdk'
    

    After:

    import { BITNET_0_7B_BASE_TQ2_0 } from '@qvac/sdk'
    import { LLAMA_TOOL_CALLING_1B_INST_Q4_K_M } from '@qvac/sdk'
    import { PARAKEET_INDIC_CONFORMER
    
  5. sdk-v0.20.1QVAC SDK v0.20.12026-09-28 · 2026-09-28 09:52 UTC
    查看更新说明

    📦 NPM: https://www.npmjs.com/package/@qvac/sdk/v/0.20.1

    QVAC SDK 0.20.1 is a patch on 0.20.0. It exposes the remaining llama.cpp load-time placement, MoE, fit, and image-token fields, and assessModelFit now runs the engine fitter on a registry fit stub instead of coefficients alone. Mobile hosts that use react-native-bare-kit are tested against ^0.15.5 (Bare 1.33), which matches the addon graph this release installs.

    Install @qvac/sdk and @qvac/inference together at 0.20.1.

    Table of Contents

    New APIs

    llama.cpp placement, MoE, fit, and image-token load fields

    loadModel for llamacpp-completion accepts the rest of the llama.cpp load config that 0.20.0 left off the schema: CPU placement (threads, threads-batch, cpu-mask, override-tensor), MoE offload (cpu-moe, n-cpu-moe, n-cpu-ffn, moe-cache-mib), batch sizes, KV offload, weight prefetch, tensor-read laziness, fit / fit-target / fit-ctx, and image token caps.

    loadModel({
      modelSrc,
      modelType: 'llamacpp-completion',
      modelConfig: {
        threads: 8,
        'threads-batch': 16,
        'cpu-mask': 'ff',
        'override-tensor': 'blk\\.(1[0-9])\\.ffn_(up|down|gate)_exps=CPU',
        'cpu-moe': true,
        'n-cpu-moe': 2,
        'n-cpu-ffn': 4,
        'moe-cache-mib': 2048,
        'batch-size': 1024,
        'ubatch-size': 256,
        'kv-offload': false,
        'prefetch-weights': 'auto',
        'tensor-read-lazy': 'on',
        fit: true,
        'fit-target': '1024,512',
        'fit-ctx': 8192,
        'image-max-tokens': 512,
        'image-min-tokens': 64
      }
    })
    

    assessModelFit uses the engine fitter

    When the registry has published a fit description for a model, assessModelFit runs the engine fitter on that stub and returns evidence: 'native-fit'. Coefficient-only projection remains the fallback when no stub is available.

    const { verdict, evidence } = await assessModelFit({
      models: [{ model: SOME_CATALOG_CONSTANT, workload: { kind: 'llm', contextTokens: 8192 } }]
    })
    // evidence === 'native-fit' when the registry published a description for it
    

    The engine depends on @qvac/registry-client ^0.7.0 so fitBlobBinding on those stubs decodes. @qvac/sdk no longer depends on @qvac/registry-client.

    Bug Fixes

    Mobile Bare-kit host

    react-native-bare-kit ^0.15.5 is the mobile host this release is tested against. It embeds Bare 1.33, which current Bare addons require. Other kit versions still install; the addon graph must match the Bare runtime that kit embeds.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    QVAC lets you run a comprehensive range of AI workloads locally using open models across Linux, macOS, Windows, Android, and iOS.

    QVAC provides:

    • SDK for building local-first AI applications and systems in JavaScript/TypeScript and Python.
    • HTTP server for using QVAC as a local model provider. Its OpenAI-compatible API lets you connect AI tools such as OpenCode and OpenClaw, or any other compatible tool.

    Why QVAC

    • Local-first: run AI offline with inference optimized for commodity hardware, from consumer apps and embedded systems to on-premises deployments.
    • Privacy and control: keep data local, own the AI system. No cloud or third-party APIs required.
    • One SDK, all of AI: a comprehensive range of AI capabilities through one interface.
    • Cross-platform: one codebase for Linux, macOS, Windows, Android, and iOS, using JavaScript/TypeScript or Python.
    • Peer-to-peer: fetch AI models directly between peers and build unstoppable internet systems, like BitTorrent or IPFS, but for AI.

    Quickstart

    Load a model and run inference locally in a few steps. Pick your path.

    Run your first example using the JS/TS SDK.

    1. Create the examples workspace:
    mkdir qvac-examples
    cd qvac-examples
    npm init -y && npm pkg set type=module
    
    1. Install the SDK:
    npm i @qvac/sdk
    
    1. Create qvac.config.json to enable client and server logs during the run:
    {
      "loggerConsoleOutput": true,
      "loggerLevel": "info"
    }
    
    1. Create the quickstart.js script:
    import { loadModel, LLAMA_3_2_1B_INST_Q4_0, completion, unloadModel } from '@qvac/sdk';
    try {
      const modelId = await loadModel({
        modelSrc: LLAMA_3_2_1B_INST_Q4_0,
        onProgress: (p) => {
          const mb = (n) => (n / 1e6).toFixed(1);
          const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
          process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
          if (p.percentage >= 100) process.stderr.write('\n');
        },
      });
      const history = [{ role: 'user', content: 'Explain quantum computing in one sentence' }];
      const result = completion({ modelId, history, stream: true });
      for await (const token of result.tokenStream) {
        process.stdout.write(token);
      }
      await unloadModel({ modelId });
    } catch (error) {
      console.error('✖', error);
      process.exit(1);
    }
    
    1. Run the quickstart script:
    QVAC_CONFIG_PATH=./qvac.config.json node quickstart.js
    

    You'll see the model download first. Then QVAC will stream the response tokens and print them to the terminal.

    Run your first example using the Python SDK.

    1. Create the examples workspace:
    mkdir qvac-examples-py
    cd qvac-examples-py
    python -m venv .venv
    source .venv/bin/activate
    
    1. Install the package (self-contained — bundles the QVAC worker and Bare runtime, no Node.js required):
    # Replace <version> with the release you want, e.g. sdk-v0.17.0:
    pip install tetherto-qvac-sdk \
      -f https://github.com/tetherto/qvac/releases/expanded_assets/sdk-v<version>
    
    1. Create the quickstart.py script:
    import asyncio
    import sys
    
    from tetherto.qvac_sdk import Client, completion, load_model, unload_model
    from tetherto.qvac_sdk.models import LLAMA_3_2_1B_INST_Q4_0
    
    
    def print_progress(p):
        line = f"▸ Downloading {p.percentage:.0f}% ({p.downloaded / 1e6:.1f}/{p.total / 1e6:.1f} MB)"
        print(line, end="\r" if sys.stderr.isatty() else "\n", file=sys.stderr)
        if p.percentage >= 100:
            print(file=sys.stderr)
    
    
    async def main():
        async with Client() as client:
            t = client.transport
            try:
                model_id = await load_model(
                    t, model_src=LLAMA_3_2_1B_INST_Q4_0, on_progress=print_progress
                )
                run = completion(
                    t,
                    model_id=model_id,
                    history=[
                        {"role": "user", "content": "Explain quantum computing in one sentence"},
                    ],
                )
                async for event in run.events:
                    if event.type == "contentDelta":
                        sys.stdout.write(event.text)
                        sys.stdout.flush()
                print()
                await unload_model(t, model_id)
            except Exception as error:
                print(f"✖ {error}", file=sys.stderr)
                return 1
        return 0
    
    
    if __name__ == "__main__":
        sys.exit(asyncio.run(main()))
    
    1. Run the quickstart script:
    python quickstart.py
    

    You'll see the model download first. Then QVAC will stream the response tokens and print them to the terminal.

    Launch the server with the CLI, then use QVAC as model provider for OpenAI-compatible tools like OpenCode and OpenClaw.

    1. Install the CLI globally (this also installs @qvac/sdk as a transitive dependency):
    npm install -g @qvac/cli
    
    1. Create the examples workspace:
    mkdir qvac-server
    cd qvac-server
    
    1. Create the qvac.config.json declaring one model to serve:
    {
      "serve": {
        "models": {
          "my-llm": {
            "model": "QWEN3_600M_INST_Q4",
            "default": true,
            "config": { "ctx_size": 8192 }
          }
        }
      }
    }
    
    1. Start the server (bound to 127.0.0.1:11434 by default):
    qvac serve openai
    

    The model downloads on first start and is preloaded into memory. You'll see progress in the server output.

    1. From another terminal, hit it with any OpenAI-compatible client. A minimal curl:
    curl http://localhost:11434/v1/chat/completions \
      -H 'Content-Type: application/json' \
      -d '{
        "model": "my-llm",
        "messages": [{"role": "user", "content": "Explain quantum computing in one sentence"}]
      }'
    

    The response comes back as a single JSON payload with the model's answer. Add "stream": true to the body to get an SSE stream instead.

    1. Point your AI tool at the server: open its model provider settings and add a new OpenAI-compatible provider with base URL http://localhost:11434/v1, any string as the API key, and my-llm as the model name.

    [!IMPORTANT] Setup varies by tool, and we ship dedicated plugins for some of them (like OpenCode and OpenClaw) that run the server for you. See Connect AI tools to QVAC for details.

    ⭐ If QVAC saves you from shipping yet another cloud dependency, give it a star, it helps other developers find the project!

    AI capabilities

    TaskDescription
    Text generationLLM inference for text generation and chat via Fabric LLM.
    Text embeddingsVector embedding generation for semantic search, clustering, and retrieval.
    RAGOut-of-the-box retrieval-augmented generation workflow.
    Fine-tuningAdapting LLMs to domain-specific tasks via LoRA.
    MultimodalLLM inference over text, images, and other media in one context.
    Image generationText-to-image and image-to-image generation via a Diffusion backend.
    Video generationText-to-video and image-to-video generation via a Diffusion backend.
    Music generationGenerate music from text, lyrics, and musical controls via ACE-Step or MiniMax-Music3 (desktop). The AudioGen addon exposes independent ACE-Step backend selection, opt-in WebGPU, Apple Core ML sidecars, and memory preflight for the selected placement. Native dependency versions are declared in the AudioGen manifest.
    TranscriptionSpeech-to-text via a Whisper backend, NVIDIA Parakeet, TranscribePsy EU and EU-sub (full 25-language EU with CAFE adapters and language routing, or the eight-language EU-sub), or MOSS-Transcribe-Diarize (speaker-labelled transcripts with hotwords, fused CPU encoder attention and metadata-only memory fit via assessFit).
    Speaker diarizationWhisper tinydiarize speaker turns, four-speaker Sortformer, up to eight-speaker Nemotron 3 Diarization, Parakeet text per speaker turn with a separate diarizer, and speaker-labelled MOSS-Transcribe-Diarize transcripts through @qvac/asr-ggml. The addon exposes native Parakeet backend selection and streaming token IDs, finality and event timing, delivering transcript chunks before their end-of-turn boundary.
    Audio decodingFFmpeg audio decoder with streaming PCM output and a default 64 MiB decoded-output limit.
    Text-to-SpeechSpeech synthesis with selective MOSS Delay text projection on Metal and single-reference MOSS-TTSD preparation, incremental Audio8 PCM streaming, speech-to-speech replies and text-to-sound-effects generation via a GGML backend, with memory preflight for MOSS-SoundEffect, LavaSR denoising on Android Mali GPUs with explicit Core ML denoiser/enhancer options on Apple, and Pocket TTS (CPU, Metal, CUDA, Vulkan and OpenCL through the addon). Native engine controls expose MOSS sampling/budgets, Supertonic precision/warm-up, Parler Core ML selection and CosyVoice token replay. Exact native dependency versions are declared in the package manifest. Chatterbox and CosyVoice3 Core ML sidecars are optional on Apple platforms. Re-export existing CosyVoice3 LM sidecars after upgrading.
    TranslationNeural machine translation, via Fabric LLM and Bergamot.
    BCIBrain–computer interface transcription via a Whisper backend.
    VLAVision-language-action for robot control via a GGML backend.
    OCRExtract text from images via ONNX Runtime or GGML backends. See OCR GPU selection (main-gpu) to select a GGML GPU by registry index or device class.
    Image classification and embeddingsClassify images with MobileNet or generate MegaLoc descriptors for image retrieval via a GGML/Fabric backend.

    Peer-to-peer

    QVAC's built-in P2P capabilities let you build unstoppable internet systems without depending on centralized infrastructure:

    • Fetch models: download AI models directly from peers through a distributed model registry, removing the need for centralized model hosting and distribution. The registry also serves weightless descriptions of models, their settings and tensor list without the weights, so whether a model fits in memory can be assessed before it is downloaded.
    • Blind relays: route traffic through relay peers when devices cannot connect directly across NATs and firewalls, keeping the network connected without centralized infrastructure.

    Resources

    Explore and use QVAC:

    ResourceDescription
    DocsComprehensive QVAC documentation.
    ExamplesSample apps and PoCs built with QVAC SDK.
    Local model providerUse QVAC as a local model provider connected to your favorite AI tools.
    QV.ACGet to know our local AI assistant.
    Support and communityWe gather on Discord and Keet. Ask for help, give feedback, and discuss QVAC.
    BlogTutorials, deep dives, engineering notes, and announcements.
    EcosystemDiscover the broader QVAC ecosystem.
    ResearchPapers, datasets, and models optimized for edge devices.
    Our visionLearn why Tether built QVAC.

    Contributing

    We welcome contributions! Feel free to open a pull request, report bugs, or share ideas through issues.

    See CONTRIBUTING for details.

    Banners and badges

    Built something with QVAC? Add a badge to your README to show it and help others discover QVAC:

    Built with QVAC   Built with QVAC

    [![Built with QVAC](https://raw.githubusercontent.com/tetherto/qvac/refs/heads/main/docs/branding/qvac-badge-green-light.svg)](https://github.com/tetherto/qvac)
    

    The full set of banners and light/dark and inline badge variants, with copy-paste snippets, lives in BADGES.md.