服务器与 Web UI

TensorSharp.Server 是一个 ASP.NET Core 应用,托管单个 GGUF 模型,并在同一端口上暴露浏览器聊天 UI 以及兼容 Ollama 和 OpenAI 的 REST API。连续批处理引擎负责并发。

启动服务器

约 30 秒快速开始(Gemma 4 E4B)

按平台安装 .NET 10 SDK、Git、CMake 与 curl,然后在终端粘贴下面的命令。复制并运行这些命令约需 30 秒;7.48 GiB 的模型下载与首次还原/构建耗时更长,取决于网络速度与机器性能。它会通过原生 GGML 桥接托管仓库基准已验证的 Gemma 4 E4B Q8_0,使用推荐的公开 ggml-org 文件。下面的代码块面向 Linux + NVIDIA(CUDA 构建还需要 CUDA Toolkit):

git clone https://github.com/zhongkaifu/TensorSharp.git
cd TensorSharp
TENSORSHARP_GGML_NATIVE_ENABLE_CUDA=ON dotnet build TensorSharp.slnx -c Release -p:TensorSharpSkipMlxNative=true
curl --create-dirs --fail -L "https://huggingface.co/ggml-org/gemma-4-E4B-it-GGUF/resolve/main/gemma-4-E4B-it-Q8_0.gguf?download=true" -o models/gemma-4-E4B-it-Q8_0.gguf
dotnet run --project TensorSharp.Server -c Release --no-build -- --model models/gemma-4-E4B-it-Q8_0.gguf --backend ggml_cuda

Apple Silicon 请省略 CUDA 环境变量并使用 ggml_metal;受支持的 Windows/Linux Vulkan GPU 请改为请求 TENSORSHARP_GGML_NATIVE_ENABLE_VULKAN=ON 并使用 ggml_vulkan;没有受支持的 GPU 时可省略该环境变量并使用 ggml_cpu。占用内存更低的 gemma-4-E4B-it-Q4_K_M.gguf 位于同一仓库。纯文本不需要投影器;图像、视频或音频还需匹配的 mmproj-gemma-4-E4B-it-Q8_0.gguf,并通过 --mmproj 传入。Windows PowerShell 与完整平台语法见快速开始

在第二个终端中验证 OpenAI 兼容端点:

curl -s http://localhost:5000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model":"gemma-4-E4B-it-Q8_0.gguf","messages":[{"role":"user","content":"Reply with one short hello."}],"max_tokens":32}'

API 基址是 http://localhost:5000。内置聊天 UI 位于 http://localhost:5000/index.htmlGET / 是存活检查接口,返回 "TensorSharp.Server is running"

📌

推理必须在启动时传入 --model。服务器只托管启动时指定的 GGUF,以及可选且必须显式传入的 --mmproj;它不会扫描模型目录或自动探测投影器。/api/models/load 只能用其他受支持后端重新加载同一启动组合。无模型进程不能在运行时选择 GGUF。监听地址固定为 http://0.0.0.0:5000,没有端口参数。

🔐

服务端没有内置 API Key 身份验证或 TLS,并监听所有网络接口。本机使用时请依靠主机防火墙;需要远程访问时应置于带身份验证的 HTTPS 反向代理之后,不要把 5000 端口直接暴露给不可信网络。

已构建的源码目录

构建完成后,从仓库根目录运行这些命令。它们会调用 TensorSharp.Server/bin/TensorSharp.Server.dll;该输出目录也包含复制好的原生库与 wwwroot/。当前 v3.0.5.0 GitHub Release 没有附带二进制压缩包。

# Apple Silicon / Metal
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --model ./models/model.gguf --backend ggml_metal

# NVIDIA / GGML CUDA
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --model ./models/model.gguf --backend ggml_cuda

# AMD、Intel 或 NVIDIA / Vulkan;先查看设备索引
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --list-gpus
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --model ./models/model.gguf --backend ggml_vulkan --gpu-device 1

# 多模态:投影器始终显式指定
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --model ./models/model.gguf --mmproj ./models/mmproj.gguf --backend ggml_cuda

服务器级默认采样

默认值会填补请求未提供的任何字段;逐请求的值始终优先。

dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --model ./models/model.gguf --backend ggml_metal \
    --temperature 0.7 --top-p 0.9 --top-k 40 --repeat-penalty 1.1 \
    --presence-penalty 0.0 --frequency-penalty 0.0 --seed 42 \
    --stop "</s>" --stop "<|endoftext|>"

Web UI 功能

打开 http://localhost:5000/index.html。浏览器界面支持:

配置文件(--config

可以用 --config 传入一个 JSON 文件,取代冗长的命令行;CLI 读取相同格式。命令行参数始终优先——先应用文件中的值,命令行上再次给出的参数会覆盖它们,因此可以在多台主机上复用同一个文件,只覆盖需要变化的部分。--config 可重复以叠加多个文件(后者优先)。允许注释与尾随逗号。

# 从文件读取全部参数;本次仅覆盖后端
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --config config/server-basic.json
dotnet TensorSharp.Server/bin/TensorSharp.Server.dll --config config/server-basic.json --backend ggml_cpu

键名与下方长选项名相同(可带或不带前缀 --)。字符串/数字展开为 --key valuetrue 展开为裸开关 --key,数组展开为重复的标志(如 "stop": ["</s>", "<|eot|>"])。

变量。"variables" 中定义一次共享值,用 ${name} 在任意字符串值中引用(未定义的名称回退到同名环境变量)。可以定义任意多个根路径——位于不同目录的模型各用一个。

自动下载。 任何文件参数都可以写成带本地 path 与一个或多个 urls 的对象。若 path 不存在,则从第一个可用 URL 下载(镜像按顺序尝试),保存到该路径,之后复用;进度打印到 stderr,可选的 sha256 用于校验。

{
  "variables": { "modelRoot": "C:/models", "repo": "https://huggingface.co/unsloth/gemma-4-E4B-it-GGUF/resolve/main" },
  "backend": "ggml_cuda",
  "max-tokens": 4096,
  "continuous-batching": true,
  "stop": ["</s>", "<|eot|>"],
  "model":  { "path": "${modelRoot}/gemma-4-E4B-it-Q8_0.gguf", "urls": [ "${repo}/gemma-4-E4B-it-Q8_0.gguf" ] },
  "mmproj": { "path": "${modelRoot}/gemma-4-E4B-mmproj-F16.gguf", "urls": [ "${repo}/mmproj-F16.gguf" ] }
}

开箱即用的示例见仓库 config/ 目录(cli-basic.jsonserver-basic.jsonvariables.jsonauto-download.jsonqwen-image-edit.json)——每个都使用真实、公开、无需授权的 URL,因此在全新机器上也能直接运行。完整说明见 config/README.md

服务器选项

选项说明
--model <path>要托管的 GGUF 文件(推理必需)。
--mmproj <path>显式多模态投影器 GGUF;只写文件名时相对于模型目录解析(传 none 可禁用)。需要 --model;不会自动扫描投影器。
--backend <type>默认后端:cpucudamlxggml_cpuggml_metalggml_cudaggml_vulkan
--tp <N>张量并行度 —— 把托管的模型切分到本机 N 张 GPU 上(默认:1;环境变量 TENSORSHARP_TP_DEGREE)。需要 --backend cudaggml_cudaggml_vulkan。→ 多 GPU 与多节点
--tp-node-id <N> / --tp-peers <list>加入多节点 TP 集群:本节点的 0 起始编号,以及所有节点共享且顺序一致的 host:port 列表。服务端只能是节点 0(负责采样并对外提供 HTTP 的 driver);其余节点运行 TensorSharp.Cli worker。
--gpu-device <N>ggml_vulkan 后端在多 GPU 主机上使用的 Vulkan 设备索引(默认:0;环境变量 TS_GGML_VULKAN_DEVICE)。
--list-gpus列出 ggml-vulkan 可见的 Vulkan 设备(索引 + 显卡名称)后退出。
--help打印完整参数说明后退出;不带任何参数时也会显示。推理始终需要启动参数 --model
--config <path>从 JSON 配置文件读取参数(命令行参数会覆盖它)。支持 ${变量} 与通过 { "path": ..., "urls": [...] } 自动下载模型。可重复。
--max-tokens <N>Web UI 请求未指定时的默认生成上限(默认:20000);Ollama/OpenAI 兼容端点省略请求级上限时使用 200
--temperature / --top-k / --top-p / --min-p请求未提供时的默认采样值(默认 0.8 / 40 / 0.9 / 0)。
--repeat-penalty / --presence-penalty / --frequency-penalty / --seed默认惩罚与随机种子(默认 1.1 / 0 / 0 / -1)。
--stop <string>默认停止序列(可重复)。逐请求的 stop 会替换该列表。
--continuous-batching / --no-continuous-batching启用(默认)或禁用迭代级分页批处理。别名:--paged-batching
--mtp-spec / --no-mtp-spec启用 / 禁用 NextN / MTP 推测解码(默认关闭);只在模型确实带有 MTP/NextN 草稿头时生效。→ MTP
--mtp-draft <N>每个推测步草拟的最大 token 数(默认 8)。
--mtp-pmin <f>保留某 token 所需的草稿头最低置信度(默认 0.75)。
--mtp-draft-model <path>独立的 MTP 草稿 GGUF(Gemma 4 的 gemma4-assistant)。Qwen 3.6 的 NextN 位于主 GGUF 中,不需要此参数;显式草稿无法激活时启动会失败。
--prefill-chunk-size <N>每个调度步的最大 prefill token 数(设置 TS_SCHED_PREFILL_CHUNK)。
--kv-cache-dtype <type>KV 缓存精度:f32f16q8_0q4_0(默认自动,由后端 / 模型选择;环境变量 KV_CACHE_DTYPE)。
--paged-kv / --no-paged-kv独立 PagedKvCacheManager 的旧兼容开关,不在当前服务请求路径上;活跃请求 KV 由引擎管理。
--paged-kv-block-size / --paged-kv-ram-mb / --paged-kv-ssd-dir / --paged-kv-ssd-mb旧的独立 paged-KV 调参。当前服务请求请使用下方 TS_SCHED_* 引擎设置。
--paged-kv-quant-bits <b>旧的独立 TurboQuant 设置;服务端参数接受 048(运行时环境变量与 CLI 还接受 2)。
--qwen-image-vae / --qwen-image-vl / --qwen-image-mmproj <path>覆盖解析到的 Qwen-Image-Edit 伴随 GGUF(VAE / Qwen2.5-VL 文本编码器 / mmproj)。
--qwen-image-lora <path>Qwen-Image-Edit Lightning 蒸馏 LoRA(.safetensors),合并进 DiT;自动推导去噪步数,并将 CFG 切换为 1.0。

逐请求字段(temperaturetop_pseedstop ……)始终覆盖这些服务器级默认值;默认值只填补客户端省略的部分。

环境变量

变量说明
BACKEND未传 --backend 时的默认后端(默认:macOS 上为 ggml_metal,其他平台为 ggml_cpu)。
MAX_TOKENS默认最大生成长度(默认:20000)。
TS_PDF_MAX_PAGES上传 PDF 时读取的页数上限,文本提取与页面图像渲染均遵循(默认:0 = 全部页面;CLI --pdf 同样遵循)。
VIDEO_SAMPLE_FPS / VIDEO_MAX_FRAMES每秒视频采样的帧数 / 可选的抽帧上限。
TS_FUSED_QKNORM_ROPEDirect cuda 后端上 Qwen 3.5/3.6 文本 prefill 的融合 QK-Norm + RoPE CUDA 内核(默认开启;0 关闭)。
TENSORSHARP_TEMPERATURE…_TOP_K…_TOP_P…_MIN_P当参数与请求体都未设置时的默认采样值。
TENSORSHARP_REPEAT_PENALTY…_PRESENCE_PENALTY…_FREQUENCY_PENALTY…_SEED默认惩罚与随机种子。
TENSORSHARP_LOG_LEVEL / …_LOG_DIR / …_LOG_FILE日志级别、目录与文件开关(CLI 同样遵循)。
DIFFUSION_STEPS / DIFFUSION_MAX_BATCHDiffusionGemma 每块去噪步数 / 批处理的最大并发扩散请求数。
TENSORSHARP_TP_DEGREE把托管模型切分到本机多少张 GPU 上(默认:1);服务端也支持 --tp N 参数。需要 --backend cudaggml_cudaggml_vulkan。→ 多 GPU 与多节点
TENSORSHARP_TP_DEVICES各 TP rank 使用的 GPU 序号,例如 0,2(默认 0..tp-1)。用于 GGML 后端。
TENSORSHARP_TP_NODE_ID / TENSORSHARP_TP_PEERS把张量并行扩展到多台机器:本节点的 0 起始编号,以及所有节点共用的逗号分隔 host:port 列表。两者必须同时设置。
TS_KV_CACHE_REDIS_URL / TS_KV_CACHE_REDIS_TTL_MINUTES把分页 KV 块持久化到 Redis,实现跨会话(乃至跨进程)复用,以及条目 TTL(分钟,默认 14400 = 不过期)。CLI:--redis-url / --paged-kv-redis-url / --paged-kv-redis-ttl
TS_RESPONSES_STORE_REDIS_URL用 Redis 而非进程内存承载 OpenAI Responses API 存储。CLI:--redis-url

当前二进制固定监听 http://0.0.0.0:5000;Docker Space 镜像在构建时把该常量改为 7860

连续批处理调参

调度器 / 引擎的旋钮在进程启动时读取。通过环境变量(或会被翻译成它们的 --continuous-batching 系列参数)设置。

变量说明
TS_SCHED_DISABLE_BATCHED1 强制逐序列 KV 交换,即使模型支持批处理(= --no-continuous-batching)。
TS_SCHED_MAX_BATCHED_TOKENS每步 token 预算(默认 4096)。
TS_SCHED_MAX_RUNNING_SEQS最大在飞序列数(默认 16)。
TS_SCHED_PREFILL_CHUNK每步最大 prefill token 数(默认 1024)。
TS_SCHED_SOLO_PREFILL_CHUNK系统中最多一个序列时的 prefill 分块大小,会限制所有独占 prefill 分块(默认 8192)。
TS_SCHED_DECODE_QUANTUM切换序列前的 decode token 数(默认 256 = 块大小)。
TS_SCHED_NUM_BLOCKS / TS_SCHED_BLOCK_SIZE引擎池中的物理块数(默认 256) / 每块 token 数(默认 256)。
TS_SCHED_PREFIX_CACHE0 禁用跨请求的块哈希前缀共享。
TS_<FAMILY>_BATCHED=0逐模型的逃生口(如 TS_GEMMA4_BATCHED=0),回退到逐序列 KV 交换。

完整的环境变量面(MLX 调参、MTP 旋钮、扩散)见 API 参考 页与高级页。