Curiosity Spark
Models on your hardware.
APIs you already use.
Run open language models on your own servers and call them with the OpenAI and Anthropic SDKs your code already uses, or from Curiosity Studio. Prompts, answers and models never leave your network.
04 · Nothing leaves your network
What it does
The model endpoint your code already knows how to call
Open models on your own machines, behind the same APIs as the cloud. Your prompts stay with you.
01
No code to rewrite
OpenAI and Anthropic SDKs work as they are: change the address, keep the code. Streaming, tool calls, reasoning and structured output included.
02
Your data stays inside
Prompts, answers and model weights never leave your network. There is no provider account to sign up for.
03
Uses the hardware you have
Spark fits each model to the memory it finds, CPU or GPU, and makes room by unloading models nobody is using.
04
Every model behind one address
Chat, vision and embedding models side by side. Name a model in the request, and Spark loads it if it is not running yet.
Streaming
Streamed as it is written
Your client gets each piece of the answer as it is written, exactly as it would from a cloud API. Pick a request to watch it arrive.
Pick a request
What the client assembles
1. Confirm the isolation valves are open. 2. Look for leaks at the seal. 3. Read the last maintenance log entry.
Example answers, shortened to the text field.
curl http://localhost:8080/v1/chat/completions \
-H "Authorization: Bearer sk-spark-…" -H "Content-Type: application/json" \
-d '{"model": "smollm2-135m-instruct-q8_0", "stream": true, "messages": [{"role": "user", "content": "List three checks before a pump restart."}]}'
data: {"choices":[{"delta":{"content":"1."}}]}
data: {"choices":[{"delta":{"content":" Confirm"}}]}
data: {"choices":[{"delta":{"content":" the"}}]}
data: {"choices":[{"delta":{"content":" isolation"}}]}
data: {"choices":[{"delta":{"content":" valves"}}]}
data: {"choices":[{"delta":{"content":" are"}}]}
data: {"choices":[{"delta":{"content":" open."}}]}
data: {"choices":[{"delta":{"content":" 2."}}]}
data: {"choices":[{"delta":{"content":" Look"}}]}
data: {"choices":[{"delta":{"content":" for"}}]}
data: {"choices":[{"delta":{"content":" leaks"}}]}
data: {"choices":[{"delta":{"content":" at"}}]}
data: {"choices":[{"delta":{"content":" the"}}]}
data: {"choices":[{"delta":{"content":" seal."}}]}
data: {"choices":[{"delta":{"content":" 3."}}]}
data: {"choices":[{"delta":{"content":" Read"}}]}
data: {"choices":[{"delta":{"content":" the"}}]}
data: {"choices":[{"delta":{"content":" last"}}]}
data: {"choices":[{"delta":{"content":" maintenance"}}]}
data: {"choices":[{"delta":{"content":" log"}}]}
data: {"choices":[{"delta":{"content":" entry."}}]}
data: {"choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Models
More models on the machines you already have
Find a model on Hugging Face from the console and download it. Spark works out where it fits, and makes room when it has to. Pick a step to stop the drawing and read it.
- 01
A model loads where it fits
Spark counts what a model needs before it starts it: the weights, the cache for the conversation, the working buffers.
- 02
A second model loads beside it
Two models, side by side on one machine, each answering its own requests.
- 03
A third needs more than is free
Model C asks for 12 GB and 10 GB are free. Spark does not start it to watch it fail.
- 04
The idle model makes room
Model A has had no requests for a while, so Spark unloads it. It loads again the next time someone asks for it.
- 05
Model C runs
It loads into the room made for it. A model too large for any machine is refused, with the arithmetic.
One endpoint
Every model your teams need, at one address
Give your applications one endpoint and a choice of models. Each request names the model it wants, and Spark takes care of the rest.
- 01
One address for every model
Chat, vision and embedding requests all go to the same endpoint. Each names the model it wants.
- 02
Each request finds its model
Spark sends every request to the model it named, wherever that model is loaded.
- 03
Models answer side by side
A chat model writes, a vision model describes an image, an embedding model returns vectors for search, all at once.
- 04
Ask for a model that is not loaded
Name any model in the library. Spark loads it on the first request.
- 05
Ready, and it stays ready
It answers, and stays loaded while it is used. When nobody needs it, it makes room for others.
And the rest
Everything around the model, built in
Keys, logs, caching and more machines come with the server, not as extra services.
Fast follow up questions
The next turn of a chat picks up where the last one ended, even after other conversations came in between.
Images and search
Vision models read images sent the way OpenAI or Anthropic clients send them. Embedding models serve semantic search.
Keys that keep nothing
Create a key with zero retention, and its requests are logged without the prompt or the answer.
Every request on record
Who asked, with which key, which model, how many tokens and how long it took, step by step.
More machines
Add machines and Spark routes each request to the one that has the model loaded.
Locked by default
Every call needs an API key unless you switch that off. Put your own HTTPS proxy in front for access beyond your network.
With Studio
Give Studio a model on your own hardware
Studio takes any OpenAI compatible endpoint as its model. Spark serves one, so the tools your teams build can run on weights that stay on your machines.
01
Run Spark
Install it on a machine with room for the model and start it with a password. The console is at localhost:8080.
02
Create an API key
In the console, under API keys. Spark’s endpoint is the address with /v1 on the end.
03
Add it to Studio
Add the endpoint and the key as an OpenAI compatible provider, and name the model as the console lists it, such as smollm2-135m-instruct-q8_0.
Install
An answer in a few minutes
One command to install, one to start. Everything is in the download.
macOS · Linux
01 · Install
Downloads the latest release, checks it and puts spark on your PATH.
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.sh | sh
02 · Start it
Start it with a password for the console, and a folder for its models.
SPARK_ADMIN_PASSWORD='choose-a-password' SPARK_STORAGE="$HOME/.curiosity/spark-data" spark
What you see
curl -fsSL https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.sh | shInstalling Spark (linux-x64) downloading v26.10.6452: https://github.com/curiosity-ai/spark/releases/download/v26.10.6452/spark-26.10.6452-linux-x64.tar.gz sha256 verified installed /home/you/.curiosity/spark launcher /home/you/.curiosity/bin/spark added /home/you/.curiosity/bin to PATH in /home/you/.bashrc Spark v26.10.6452 is installed.Open a new terminal, or run this one first: export PATH="/home/you/.curiosity/bin:$PATH"Then start it with a management password (data and models go to ./storage unless SPARK_STORAGE says otherwise): SPARK_ADMIN_PASSWORD='choose-a-password' SPARK_STORAGE="$HOME/.curiosity/spark-data" sparkand open http://localhost:8080 (SPARK_PORT changes the port). SPARK_ADMIN_PASSWORD='choose-a-password' spark
Windows
01 · Install
Downloads the latest release, checks it and adds it to your PATH.
irm https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.ps1 | iex
02 · Start it
Start it with a password for the console, and a folder for its models.
$env:SPARK_ADMIN_PASSWORD = 'choose-a-password'; $env:SPARK_STORAGE = "$HOME\.curiosity\spark-data"; spark
What you see
irm https://raw.githubusercontent.com/curiosity-ai/spark/refs/heads/main/install.ps1 | iexInstalling Spark (win-x64) downloading v26.10.6452: https://github.com/curiosity-ai/spark/releases/download/v26.10.6452/spark-26.10.6452-win-x64.zip sha256 verified installed C:\Users\you\.curiosity\spark Spark v26.10.6452 is installed.Start it with a management password (data and models go to .\storage unless SPARK_STORAGE says otherwise): $env:SPARK_ADMIN_PASSWORD = 'choose-a-password'; $env:SPARK_STORAGE = 'C:\Users\you\.curiosity\spark-data'; sparkand open http://localhost:8080 (SPARK_PORT changes the port). $env:SPARK_ADMIN_PASSWORD = 'choose-a-password'; spark
Docker
01 · Install
Models and settings live in the spark-data volume.
docker run -d --name spark -p 8080:8080 -v spark-data:/data \
-e SPARK_ADMIN_PASSWORD='choose-a-password' curiosityai/spark:latest
02 · On a GPU host
With the NVIDIA container toolkit on the host, add --gpus all.
docker run -d --name spark --gpus all -p 8080:8080 -v spark-data:/data \
-e SPARK_ADMIN_PASSWORD='choose-a-password' curiosityai/spark:latest
What you see
docker run -d --name spark -p 8080:8080 -v spark-data:/data -e SPARK_ADMIN_PASSWORD='choose-a-password' curiosityai/spark:latestOpen http://localhost:8080 and sign in as admin.
To upgrade, run the install command again. Your models and settings are kept.
Your first request
From install to an answer
- 01
Add a model
Open
localhost:8080, sign in asadminand search Hugging Face under Discover. A small one such asSmolLM2-135M-Instructis enough to try it. - 02
Create a key
Under API keys, create one. It is the bearer token your client sends.
- 03
Call it
Point an OpenAI SDK at
http://localhost:8080/v1, or an Anthropic SDK athttp://localhost:8080.
FAQ
Questions about Spark
Which models does Spark run?
Open models in the GGUF format, from Hugging Face or from a file you copy in: families such as Llama, Mistral, Qwen and Granite, vision models and embedding models. The console marks a model it cannot run before you download it.
Does Spark run on a GPU?
Spark places models on NVIDIA GPUs with CUDA 12 when it finds them, and runs them on the CPU otherwise, on x64 and ARM64.
Does one model serve several requests at once?
A model answers one request at a time, in the order they arrive. Different models answer side by side.
Does Spark keep my prompts?
The request log keeps prompts and answers for 30 days by default, so you can inspect them. Switch that off, or use a key with zero retention, and the content is never written to disk.
How does Studio use Spark?
Studio takes any OpenAI compatible endpoint as its model, and Spark is one. Create a key in Spark’s console and add the endpoint and key to Studio.
Can Spark serve an embedding model?
Yes. Embedding models answer the OpenAI embeddings endpoint, for semantic search.
How do I update it?
Run the install command again and restart Spark. Your models and settings are kept.
Your data. Your infrastructure.