← 开源
Trans-N-ai

swama

High-performance MLX-based LLM inference engine for macOS with native Swift implementation

InfrastructureDeploy & ServeModel HubSwift
在 GitHub 打开
增长势头
+024 小时新增 Star0.0%
593
Star
31
Fork
+0
本周
15
贡献者
创建于 2025-06-04 · 更新于 2026-10-15 · 今日第 16407 名
主要开发者
sxy-trans-nyexin9743BBBOND

Trans-N-ai/swama 排名第 16,407,有 593 个星标。

同类别比较

Trans-N-ai/swama 排名第 16,407,此处有 8 个同类条目;VictoriaMetrics/operator 排名第 16,398。

同类别比较
名称排名指标
facebookresearch/NeuralCompression16,355
语言:
Python
星标数:
597
分叉数:
57
简介:
A collection of tools for neural compression enthusiasts.
grimoire/mmdetection-to-tensorrt16,370
语言:
Python
星标数:
596
分叉数:
83
简介:
convert mmdetection model to tensorrt, support fp16, int8, batch input, dynamic shape etc.
lucienhuangfu/eLLM16,392
语言:
Rust
星标数:
595
分叉数:
56
简介:
eLLM: Run Long-Horizon Inference Faster on CPUs Than on GPUs
VictoriaMetrics/operator16,398
语言:
Go
星标数:
594
分叉数:
239
简介:
Kubernetes operator for Victoria Metrics
strongdm/leash16,428
语言:
Go
星标数:
592
分叉数:
46
简介:
Leash by StrongDM - take your AI agents for a walk
thunder-id/thunderid16,446
语言:
Go
星标数:
591
分叉数:
394
简介:
ThunderID is a high-performance, open-source identity stack designed for developers to secure and manage access for humans, AI agents, and machines through fully composable identity flows.
gzzhongqi/geminicli2api16,457
语言:
Python
星标数:
590
分叉数:
627
keldenl/gpt-llama.cpp16,458
语言:
JavaScript
星标数:
590
分叉数:
66
简介:
A llama.cpp drop-in replacement for OpenAI's GPT endpoints, allowing GPT-powered apps to run off local llama.cpp models instead of OpenAI.
关键参数与规格
关键参数与规格
参数值
语言Swift
类别Infrastructure
子类别Deploy & Serve,Model Hub
关键词LocalAI, MLX
星标数593
分叉数31
贡献者15
创建日期2025-06-04
更新日期2026-10-15
1 天星标数0
7 天星标数0
排名16,407
上次排名16,198
排名变化-209
7 天星标排名15,513
上次 7 天星标排名15,524
7 天星标排名变化11
总星标排名16,934
上次总星标排名16,907
总星标排名变化-27
README 摘录

Swama English | 中文 | 日本語 **Swama** is a local AI runtime for Apple Silicon Macs, written in Swift on Apple's MLX. It runs language, vision, embedding, speech-recognition and text-to-speech models on your Mac and serves them through an OpenAI-compatible API, a command-line tool and a menu bar app. **OpenAI-compatible API**: chat completions (streaming, tool calling, image input), a stateless subset of Responses, embeddings, audio transcription and text-to-speech (experimental). **Decision scoring

**: follows the OpenAI Decisions API and scores predicates, choices, and ratings without generating text. **Model aliases**: downloads the model from Hugging Face on first use. **Menu bar app**: runs the server in the background, installs the command and sets the context limit. Requirements Apple Silicon Mac, macOS 15. 4 or later Building from source only: Xcode with the Swift 6. 2 toolchain Install **Homebrew** **App download**: get from Releases, drag into Applications and open it. If macOS blocks the first

launch, allow it under **System Settings › Privacy & Security**. Then choose **Install Command Line Tool…** in the menu bar to add to your PATH. **From source** Quick start binds to by default, which makes the API reachable from other machines on your network. Models Any MLX model on Hugging Face can be used by its full id (for example ). 5 sizes accept images), , / / , , / / / / , variants | | Speech recognition | , , (large-v3-turbo) and / / / / , , , , , , , , , , , | | Text-to-speech (experimental) | , , , , , , , , , , , , , , , | The complete alias → model mapping is in

. FireRedASR2 is also supported by its full repository id. 0, (4B) and (4B) fail to load (for Gemma, possibly related to #23); use for image input. API The server listens on port 28100 by default ( or to change it). support matrix implements an honest, stateless subset of the OpenAI Responses API: **Supported**: string or message-item , , and parts, custom tools including multi-turn / items, / , basic sampling ( , , ), non-streaming objects, and typed SSE streaming with monotonic . Responses are not stored: there

is no retrieve/cancel/delete by response id. (OpenAI Decisions API) follows the OpenAI Decisions API (openai-openapi ). It scores a finite set of answers without generating text. ** (an explicit local model), , (1–200) and (a string of at most 128 characters, or null; accepted and ignored). : , the probability that a statement about the input is true. A is a string or a boolean and comes back with the same JSON type. must not be blank, and a blank score

level is refused (stricter than the OpenAI schema). is optional and must be unique when given. The prompt shows a boolean as / , so a string and a boolean in the same choice cannot be told apart and are refused too. Choice values must otherwise be non-empty, contain no control characters and be distinct ignoring case. A level with a description is shown as . More than 26 choices use the model's two-letter labels (AA, AB, …), as on ; a model

without enough single-token pair labels refuses them. is a string, or an array of user messages whose is a

常见问题

记录了多少星标和分叉?

Trans-N-ai/swama 有 593 个星标和 31 个分叉。

仓库排名是多少?

Trans-N-ai/swama 排名第 16,407。

记录的语言和类别是什么?

Trans-N-ai/swama 有 593 个星标,语言为 Swift,类别为 Infrastructure。

哪个仓库排名最接近?

Trans-N-ai/swama 与 VictoriaMetrics/operator 比较,后者排名第 16,398,有 594 个星标。

README

Swama

English | 中文 | 日本語

Swama is a local AI runtime for Apple Silicon Macs, written in Swift on Apple's MLX. It runs language, vision, embedding, speech-recognition and text-to-speech models on your Mac and serves them through an OpenAI-compatible API, a command-line tool and a menu bar app.

  • OpenAI-compatible API: chat completions (streaming, tool calling, image input), a stateless subset of Responses, embeddings, audio transcription and text-to-speech (experimental).
  • Decision scoring: /v1/decisions follows the OpenAI Decisions API and scores predicates, choices, and ratings without generating text.
  • Model aliases: swama run qwen3.5 "…" downloads the model from Hugging Face on first use.
  • Menu bar app: runs the server in the background, installs the swama command and sets the context limit.

Requirements

  • Apple Silicon Mac, macOS 15.4 or later
  • Building from source only: Xcode with the Swift 6.2 toolchain

Install

Homebrew

brew install swama

App download: get Swama.dmg from Releases, drag Swama.app into Applications and open it. If macOS blocks the first launch, allow it under System Settings › Privacy & Security. Then choose Install Command Line Tool… in the menu bar to add swama to your PATH.

From source

git clone https://github.com/Trans-N-ai/swama.git
cd swama/swama
swift build -c release
mv .build/release/swama .build/release/swama-bin   # the app bundles the CLI under this name

cd ../swama-macos/Swama
xcodebuild -project Swama.xcodeproj -scheme Swama -configuration Release

Quick start

swama run qwen3.5 "Hello!"                          # downloads on first use
swama run qwen3.5 "What's in this image?" -i photo.jpg
swama serve --host 127.0.0.1 --port 28100          # API server
curl http://localhost:28100/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "qwen3.5", "messages": [{"role": "user", "content": "Hello!"}]}'

swama serve binds to 0.0.0.0 by default, which makes the API reachable from other machines on your network. Pass --host 127.0.0.1 to keep it local.

Models

Any MLX model on Hugging Face can be used by its full id (for example mlx-community/Qwen3.5-9B-4bit). Common models also have short aliases:

Kind Aliases (default first)
Language qwen3.5 (35B-A3B), qwen3.5-0.8b / -2b / -4b / -9b / -27b / -122b-a10b / -397b-a17b, qwen3, qwen3-1.7b / -30b / -32b / -235b, qwen2.5, llama3.2, llama3.2-1b, llama3.3, gpt-oss, gpt-oss-120b, deepseek-r1, deepseek-r1-8b, deepseek-coder, smollm
Vision qwen3.5 (all Qwen3.5 sizes accept images), gemma3, gemma3-1b / -12b / -27b, qwen3-vl, qwen3-vl-2b / -8b / -32b / -30b / -235b, -thinking variants
Speech recognition qwen3-asr, qwen3-asr-1.7b, whisper (large-v3-turbo) and whisper-tiny / -base / -small / -medium / -large, parakeet, sensevoice, glm-asr, voxtral, canary, moonshine, nemotron-asr, cohere-transcribe, moss-transcribe-diarize, wav2vec2, mms-asr
Text-to-speech (experimental) kokoro, orpheus, qwen3-tts, marvis, chatterbox, vyvo, fish-speech, soprano, pocket-tts, echo-tts, kitten-tts, irodori-tts, omnivoice, moss-tts, moss-ttsd, moss-tts-local

The complete alias → model mapping is in ModelAliases.swift. FireRedASR2 is also supported by its full repository id. Known issue: in our testing on 2.4.0, gemma3 (4B) and qwen3-vl (4B) fail to load (for Gemma, possibly related to #23); use qwen3.5 for image input.

API

The server listens on port 28100 by default (--port or SWAMA_PORT to change it).

Endpoint Notes
GET /v1/models Downloaded models
POST /v1/chat/completions Streaming ("stream": true), tool calling, image_url input for vision models
POST /v1/responses Stateless subset — see below
POST /v1/decisions OpenAI Decisions API: scores predicates, choices and ratings without generating text — see below
POST /v1/systemone SystemOne request/response adapter over the same decision scorer — see below
POST /v1/embeddings Embedding models such as mlx-community/embeddinggemma-300m-4bit
POST /v1/audio/transcriptions Multipart upload, local speech recognition
POST /v1/audio/speech Text-to-speech (experimental)
# Image input
curl http://localhost:28100/v1/chat/completions -H "Content-Type: application/json" -d '{
  "model": "qwen3.5",
  "messages": [{"role": "user", "content": [
    {"type": "text", "text": "What do you see?"},
    {"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}]}]}'

# Tool calling
curl http://localhost:28100/v1/chat/completions -H "Content-Type: application/json" -d '{
  "model": "qwen3.5",
  "messages": [{"role": "user", "content": "What is the weather in Tokyo?"}],
  "tools": [{"type": "function", "function": {"name": "get_weather",
    "parameters": {"type": "object", "properties": {"location": {"type": "string"}}, "required": ["location"]}}}]}'

# Embeddings
curl http://localhost:28100/v1/embeddings -H "Content-Type: application/json" \
  -d '{"model": "mlx-community/embeddinggemma-300m-4bit", "input": ["Hello world"]}'

# Transcription
curl http://localhost:28100/v1/audio/transcriptions -F "file=@audio.wav" -F "model=qwen3-asr"

# Text-to-speech
curl http://localhost:28100/v1/audio/speech -H "Content-Type: application/json" \
  -d '{"model": "kokoro", "input": "Hello from Swama", "response_format": "wav"}' --output speech.wav

Voices: Orpheus dan jess leo mia tara zac zoe; Marvis conversational_a conversational_b; Qwen3-TTS and VyvoTTS en-us-1; Kokoro defaults to af_heart, KittenTTS to Bella.

/v1/responses support matrix

POST /v1/responses implements an honest, stateless subset of the OpenAI Responses API:

  • Supported: string or message-item input, instructions, input_text and input_image parts, custom function tools including multi-turn function_call / function_call_output items, tool_choice "auto"/"none", basic sampling (temperature, top_p, max_output_tokens), non-streaming Response objects, and typed SSE streaming with monotonic sequence_number.
  • Accepted with an explicit local meaning (the fixed envelope Codex CLI sends — validated, documented, never silently honoured):
    • client_metadata — client-side tracing only; validated and ignored.
    • prompt_cache_key — accepted as a hint and currently not used. Swama's local cache reuses a KV prefix by comparing actual prompt tokens, and holds one entry per model, so sessions interleaved against the same model evict each other. This is not an equivalent of the hosted prompt cache.
    • reasoning — the empty object, or summary: "auto" (what Codex sends). auto leaves the choice to the server and a local model emits no reasoning items, so producing none satisfies it.
    • include: ["reasoning.encrypted_content"] — accepted; there are no reasoning items to return.
    • parallel_tool_calls — this server never executes tools and always emits function-call items one after another, satisfying false.
    • tools[{"type":"web_search","external_web_access":false}] — accepted and then dropped before the model sees it. Codex CLI 0.147.0 advertises this tool unconditionally and no client setting removes it (tools.web_search = false only flips external_web_access), so refusing it would make the CLI unusable against Swama. This is a deliberate, narrow compatibility degradation, not support: per OpenAI's reference, external_web_access: false does not disable search — it runs web search in an offline, cache-only mode over OpenAI's own index. Swama has no such index, performs no search whatsoever, and never emits a web_search_call. Any request that genuinely needs search capability is not supported here. true, a missing or non-boolean flag, any additional key (filters, search_context_size, ...), and a tool_choice naming web_search all remain hard 400s.
  • Rejected with an explicit 400 (never silently ignored): server-side state (store: true, previous_response_id, conversation, prompt), background: true, hosted/built-in and MCP tools, Structured Outputs (text.format other than plain text, response_format), truncation: "auto", forced tool_choice, reasoning.effort and any reasoning.summary other than "auto", any other include entry, max_tool_calls, service_tier, text.verbosity, tools[].strict: true, hosted tool kinds other than the exact offline web_search shape above (including namespace — run Codex with --disable multi_agent), image URLs outside http/https/data:image/..., every unlisted top-level field, and wrong-typed known fields.
  • Responses are not stored: there is no retrieve/cancel/delete by response id.

/v1/decisions (OpenAI Decisions API)

POST /v1/decisions follows the OpenAI Decisions API (openai-openapi 4a4020d8). It scores a finite set of answers without generating text. Breaking change: the earlier SGLang prompt format 1 wire (questions with id/question/options, yes_no, label_mass, temperature, chat_template_kwargs, prompt_format_version, return_prompt_token_ids) has been removed from this route; such requests now get HTTP 400 with a message saying the SGLang prompt format 1 request shape was removed (a question with id, question, options or type yes_no); a removed top-level field alone, such as temperature on an otherwise OpenAI-shaped request, is reported as an unknown field. /v1/systemone is unchanged.

Request. model (an explicit local model), input, questions (1–200) and safety_identifier (a string of at most 128 characters, or null; accepted and ignored). Parsing is strict: an unknown field at any level is refused with HTTP 400.

  • predicate: {"type":"predicate","name"?,"instructions"}, the probability that a statement about the input is true.
  • choice: {"type":"choice","name"?,"instructions","choices":[{"value","description"?}]} with 2–255 choices. A value is a string or a boolean and comes back with the same JSON type.
  • score: {"type":"score","name"?,"instructions","levels":[{"label","description"?}]} with 2–10 ordered levels.

instructions must not be blank, and a blank score level label is refused (stricter than the OpenAI schema). name is optional and must be unique when given. Duplicate choice values are refused. The prompt shows a boolean as true/false, so a string "true" and a boolean true in the same choice cannot be told apart and are refused too. Choice values must otherwise be non-empty, contain no control characters and be distinct ignoring case. A level with a description is shown as label: description. More than 26 choices use the model's two-letter labels (AA, AB, …), as on /v1/systemone; a model without enough single-token pair labels refuses them.

input is a string, or an array of user messages {"role":"user","content":…,"type"?:"message"} whose content is a string or a list of input_text and input_image parts. Texts are joined with newlines in order and images keep their order. Images must be base64 data URLs and follow the /v1/systemone image rules below: PNG, JPEG or WebP checked by file signature, complete files, at most 4 MiB and 16 megapixels each, 8 MiB in total, and at most 4 per request (fewer than OpenAI's 128). They need a vision model. When every image sets detail: "low", images are resized to fit 512 pixels per side, which is several times faster (Qwen3.5-9B on an M5 Pro: one 1280-pixel photo drops from about 1,240 to 240 input tokens and from 1.8 s to 0.36 s); otherwise detail keeps the default resizing. Other roles, other part types and remote URLs are refused. A blank input is allowed and rendered as is.

Response. model, answers in question order, and usage. Each answer carries its name, or null when the question had none.

  • predicate: probability, the yes probability conditional on the yes/no labels.
  • choice: choice (the typed value with the highest probability; ties go to the first), probabilities as [{value, probability}] in request order, and confidence.
  • score: score (the expected level index), probabilities as [{value, label, probability}] with an integer value, and confidence.

Answers are never refusal; a request the backend cannot serve is refused as a whole with a 4xx error ({"error":{"message","type"}}; unknown models use 404). usage reports input_tokens and total_tokens; output, cached, cache-write and reasoning tokens are 0. Temperature is fixed at 1.

How it scores. Swama renders one prompt per question and reads the next-token probabilities of the answer labels (yes/no, A, B, …, or 0, 1, …), using SGLang's public prompt wording. Probabilities are normalized over those labels only; the probability left outside them is not reported. The local chat tokenizer must preserve the rendered prompt and encode every answer label as one distinct token at the answer position. The template gets enable_thinking: false; templates may ignore it. Open reasoning prefixes and a recognized single-token `` or [THINK] opener at the vocabulary maximum are rejected. This check does not certify every reasoning format or guarantee the model follows instructions. Each question starts with a fresh KV cache, independent of the chat prompt cache. Even identical low-precision weights can produce probability differences across backends and prefill layouts.

confidence uses the formulas from SGLang's SystemOne implementation. It measures concentration among the candidates, not the probability that the answer is correct. Let q be the candidate probabilities, n the number of candidates, and m the first index with maximum probability (levels in request order):

  • Choice: clamp((n * max(q) - 1) / (n - 1), 0, 1).
  • Score: max(0, 1 - sum(q[i] * abs(i - m)) / U), where U = sum(abs(i - (n - 1) / 2)) / n. This uses absolute distance and the uniform distribution's midpoint, not variance or a denominator centered on m.

For example, three choice probabilities [0.7, 0.2, 0.1] give confidence 0.55; uniform probabilities give 0, and a one-hot distribution gives 1. Validate thresholds on representative application data; confidence does not guarantee correctness.

Known limitations

  • predicate reads only lowercase labels. As in SGLang, only the lowercase yes and no tokens are scored. Many models also put probability on Yes and No. When a model prefers the capitalized form for one answer but not the other, probability can differ from the case-combined answer, and in independent testing it occasionally pointed the other way. Swama does not merge case variants; validate predicate thresholds on your own data.
  • The measured Qwen3.5 models produce bf16 logits. Two labels can tie exactly; ties go to the first option in the order given. Values can shift between Swama versions, dependency updates and backends; do not rely on bit-for-bit probability agreement across those configurations.
  • Mixture-of-experts models drift more. Against a full-precision (fp32) computation of the same 4-bit weights, centered label log-probabilities differed by up to about 0.2 for dense Qwen3.5 models (0.8B, 9B) and up to about 0.55 for Qwen3.5-35B-A3B. The top answer matched the full-precision result in all 21 reference cases we measured, but close calls on MoE models are less stable. Whether that is acceptable depends on your application.
curl -X POST http://localhost:28100/v1/decisions \
  -H "Content-Type: application/json" \
  -d '{"model":"mlx-community/Qwen3.5-0.8B-4bit","input":"My invoice charged me twice.","questions":[{"type":"predicate","name":"billing","instructions":"Is this a billing issue?"},{"type":"choice","name":"team","instructions":"Which team should handle this?","choices":[{"value":"billing"},{"value":"technical"},{"value":"sales"}]},{"type":"score","name":"urgency","instructions":"How urgent is it?","levels":[{"label":"low"},{"label":"medium"},{"label":"high","description":"needs action today"}]},{"type":"choice","instructions":"Was the customer charged correctly?","choices":[{"value":true},{"value":false}]}]}'

Response from that model (formatted):

{"model":"mlx-community/Qwen3.5-0.8B-4bit","answers":[
  {"type":"predicate","name":"billing","probability":0.8175744761936437},
  {"type":"choice","name":"team","choice":"billing","probabilities":[{"value":"billing","probability":0.9478362250325003},{"value":"technical","probability":0.047189986937231164},{"value":"sales","probability":0.004973788030268673}],"confidence":0.9217543375487502},
  {"type":"score","name":"urgency","score":1.922966354728045,"probabilities":[{"value":0,"label":"low","probability":0.015163456120649954},{"value":1,"label":"medium","probability":0.04670673303065524},{"value":2,"label":"high","probability":0.9381298108486948}],"confidence":0.8844495320920672},
  {"type":"choice","name":null,"choice":true,"probabilities":[{"value":true,"probability":0.5621765008857981},{"value":false,"probability":0.4378234991142019}],"confidence":0.12435300177159614}],
 "usage":{"input_tokens":184,"input_tokens_details":{"cached_tokens":0,"cache_write_tokens":0},"output_tokens":0,"output_tokens_details":{"reasoning_tokens":0},"total_tokens":184}}

/v1/systemone (SystemOne OpenAPI 0.2.0)

POST /v1/systemone accepts an explicit local model, textual or structured state, and a map of named questions. It calls the same engine, model pool, prompt wording and scorer as /v1/decisions. noul maps to yes/no and returns noul = p(yes); choice returns the selected name, probabilities and confidence; score returns the expected level, probabilities, confidence and the original criteria in legend. The response has model, answers and usage (input_tokens, output_tokens: 0). x_label_mass is the total probability of the answer labels against the full vocabulary; a low value means the model may prefer an answer outside the requested set. Confidence remains concentration, not calibrated correctness. The model/template and lowercase yes/no limitations of /v1/decisions above also apply.

Swama's current backend accepts 2–26 choices, 2–10 score levels, and non-empty instructions. Single-option questions, empty or omitted instructions, invalid rubrics, and unsupported counts receive a readable 4xx refusal. No question text or probability is invented to work around a refusal. Validation errors use HTTP 400; unknown models use 404. Capacity refusals include the phrases recognized by Decision Index's HTTP engine. Duplicate JSON object keys are rejected instead of overwriting the earlier value.

Question and choice-criteria maps retain request order; that order determines labels and the first winner on ties. String state is passed through. Objects and arrays render as compact Unicode JSON in their original member order, following SGLang render_text (openai/serving_decisions.py:369–374, frozen commit eb9c9ee9). For an exact comparison, send that same rendered text as the Decisions input string. Rubric descriptions may be strings, objects or arrays; the score answer echoes their original JSON values in legend. Temperature, prompt version and token-ID-return fields are refused on this route. chat_template_kwargs supports only enable_thinking: false.

The official Python SDK and JavaScript SDK can call this endpoint with a local base URL and model. An SDK API key placeholder is needed by their constructors; Swama does not use it for authentication. Model discovery keeps the OpenAI-shaped /v1/models. Pass an explicit local model name to TypeSafe SDK calls; its client.models.list() expects a different catalog format.

Images (Cloudflare Clef extension). An optional top-level images array follows Clef's System One extension: up to 4 images placed before the state, each either a base64 data URL string ("data:image/png;base64,...") or an object {"content_type": "image/png", "base64": "..."}. Only PNG, JPEG and WebP are accepted, judged by the file signature; a declared type that does not match the bytes is refused, and so is a truncated file. Limits: 4 MiB and 16 megapixels per image (read from the header before decoding), 8 MiB decoded in total, and a 13 MiB request body (HTTP 413). Remote URLs and video are refused. Images need a vision model and share the chat path's multimodal context limit (4096 tokens). Images are resized the way the chat path resizes them (up to 1344 px for Qwen3.5), so in practice Qwen3.5-9B fits at most 3 images per request; a request over the limit is refused with maximum context length. "images": [] is the same as no field. /v1/decisions takes images only in the OpenAI format, as input_image parts.

from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

with TypeSafeClient(
    base_url="http://127.0.0.1:28100",
    api_key="local",
    model="mlx-community/Qwen3.5-0.8B-MLX-4bit",
) as client:
    result = client.system_one(
        state={"document": "I was charged twice. Please help."},
        questions={
            "team": Choice(instructions="Which team?", criteria={"billing": None, "technical": None}),
            "billing": Noul(instructions="Is this a billing issue?"),
            "urgency": Score(instructions="How urgent?", criteria=["Can wait", "Needs attention today"]),
        },
    )
    print(result.choices["team"].choice)

Command line

Command Purpose
swama run One-off generation. -i image (repeatable), -t temperature, --top-p, -n max tokens, --repetition-penalty, --no-stream
swama serve Start the API server (--host, --port) — also the default when no command is given
swama pull Download a model or alias
swama list [--format json] Downloaded models
swama rm Delete a downloaded model
swama transcribe Speech to text (-m model, -l language, -f simple|json|verbose)
swama create -n Register a model directory you already have under a name
swama logs [--follow] Read the JSONL diagnostics log
swama menubar Run as a menu bar app

run and serve accept --context-limit (default 16384 tokens).

Environment variables: SWAMA_PORT (server port), SWAMA_MODELS (model directory, default ~/.swama/models), SWAMA_CONTEXT_LIMIT, SWAMA_REGISTRY (HUGGING_FACE or MODEL_SCOPE), SWAMA_PROMPT_CACHE=0 (disable prompt caching), SWAMA_DIAGNOSTICS_PATH (diagnostics log location), SWAMA_DIAGNOSTICS_DISABLED=1 (turn the log off).

Development

The Swift package is in swama/ (swift build, swift test) and the macOS app in swama-macos/. See CONTRIBUTING.md for the workflow and SECURITY.md for reporting vulnerabilities.

Built on mlx-swift, mlx-swift-lm, mlx-audio-swift, swift-transformers, swift-nio and swift-argument-parser.

License

MIT — see LICENSE. Questions and bug reports: Issues · Discussions.

排名相邻
同类项目