Instructions to use KernelMedia/marquee-ai with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use KernelMedia/marquee-ai with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="KernelMedia/marquee-ai") messages = [ {"role": "user", "content": "Who are you?"}, ] pipe(messages)# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("KernelMedia/marquee-ai", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- llama.cpp
How to use KernelMedia/marquee-ai with llama.cpp:
Install (macOS, Linux)
curl -LsSf https://llama.app/install.sh | sh # Start a local OpenAI-compatible server with a web UI: llama serve -hf KernelMedia/marquee-ai:Q6_K # Run inference directly in the terminal: llama cli -hf KernelMedia/marquee-ai:Q6_K
Install from WinGet (Windows)
winget install llama.cpp # Start a local OpenAI-compatible server with a web UI: llama serve -hf KernelMedia/marquee-ai:Q6_K # Run inference directly in the terminal: llama cli -hf KernelMedia/marquee-ai:Q6_K
Use pre-built binary
# Download pre-built binary from: # https://github.com/ggerganov/llama.cpp/releases # Start a local OpenAI-compatible server with a web UI: ./llama-server -hf KernelMedia/marquee-ai:Q6_K # Run inference directly in the terminal: ./llama-cli -hf KernelMedia/marquee-ai:Q6_K
Build from source code
git clone https://github.com/ggerganov/llama.cpp.git cd llama.cpp cmake -B build cmake --build build -j --target llama-server llama-cli # Start a local OpenAI-compatible server with a web UI: ./build/bin/llama-server -hf KernelMedia/marquee-ai:Q6_K # Run inference directly in the terminal: ./build/bin/llama-cli -hf KernelMedia/marquee-ai:Q6_K
Use Docker
docker model run hf.co/KernelMedia/marquee-ai:Q6_K
- LM Studio
- Jan
- vLLM
How to use KernelMedia/marquee-ai with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "KernelMedia/marquee-ai" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KernelMedia/marquee-ai", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker
docker model run hf.co/KernelMedia/marquee-ai:Q6_K
- SGLang
How to use KernelMedia/marquee-ai with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "KernelMedia/marquee-ai" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KernelMedia/marquee-ai", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "KernelMedia/marquee-ai" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "KernelMedia/marquee-ai", "messages": [ { "role": "user", "content": "What is the capital of France?" } ] }' - Ollama
How to use KernelMedia/marquee-ai with Ollama:
ollama run hf.co/KernelMedia/marquee-ai:Q6_K
- Unsloth Desktop
- Pi
How to use KernelMedia/marquee-ai with Pi:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf KernelMedia/marquee-ai:Q6_K
Configure the model in Pi
# Install Pi: npm install -g @earendil-works/pi-coding-agent # Add to ~/.pi/agent/models.json: { "providers": { "llama-cpp": { "baseUrl": "http://localhost:8080/v1", "api": "openai-completions", "apiKey": "none", "models": [ { "id": "KernelMedia/marquee-ai:Q6_K" } ] } } }Run Pi
# Start Pi in your project directory: pi
- Docker Model Runner
How to use KernelMedia/marquee-ai with Docker Model Runner:
docker model run hf.co/KernelMedia/marquee-ai:Q6_K
- Lemonade
How to use KernelMedia/marquee-ai with Lemonade:
Pull the model
# Download Lemonade from https://lemonade-server.ai/ lemonade pull KernelMedia/marquee-ai:Q6_K
Run and chat with the model
lemonade run user.marquee-ai-Q6_K
List all available models
lemonade list
- Hermes Agent
How to use KernelMedia/marquee-ai with Hermes Agent:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf KernelMedia/marquee-ai:Q6_K
Configure Hermes
# Install Hermes: curl -fsSL https://hermes-agent.nousresearch.com/install.sh | bash hermes setup # Point Hermes at the local server: hermes config set model.provider custom hermes config set model.base_url http://127.0.0.1:8080/v1 hermes config set model.default KernelMedia/marquee-ai:Q6_K
Run Hermes
hermes
- Atomic Chat
- OpenClaw
How to use KernelMedia/marquee-ai with OpenClaw:
Start the llama.cpp server
# Install llama.cpp: brew install llama.cpp # Start a local OpenAI-compatible server: llama serve -hf KernelMedia/marquee-ai:Q6_K
Configure OpenClaw
# Install OpenClaw: npm install -g openclaw@latest # Register the local server and set it as the default model: openclaw onboard --non-interactive --mode local \ --auth-choice custom-api-key \ --custom-base-url http://127.0.0.1:8080/v1 \ --custom-model-id "KernelMedia/marquee-ai:Q6_K" \ --custom-provider-id llama-cpp \ --custom-compatibility openai \ --custom-text-input \ --accept-risk \ --skip-health
Run OpenClaw
openclaw agent --local --agent main --message "Hello from Hugging Face"
Marquee
v1.1 ยท contract v1 ยท base Qwen3-4B-Instruct-2507
Turns one item in a media library into Plex-style rows of other items in that same library. Built for self-hosted media servers.
IN: "The Sopranos"
OUT:
Shows like The Sopranos Gomorrah, Boardwalk Empire, The Wire, ZeroZeroZero
More from Tim Van Patten Game of Thrones, Black Mirror, Boardwalk Empire
More with Edie Falco Nurse Jackie, Oz
Shot by Alik Sakharov Game of Thrones, House of Cards
Read this before downloading the weights
The model alone does nothing useful. It decides which rows to show, their order, and what to call them. It does not choose what goes in them -- a retriever does, by joining your library on shared cast, crew and franchise, and by embedding similarity.
The model never even sees item ids. It answers with index references into candidates it was handed, so it cannot invent a title that isn't in your library. Hallucination isn't low here, it's structurally impossible.
pip install marquee-ai
Download
hf download KernelMedia/marquee-ai --local-dir marquee
cd marquee && ollama create marquee -f Modelfile
~3.6 GB: the model plus a catalog of ~195,000 films and shows with full cast and crew.
Requirements
| VRAM | ~4.7 GB (Q6_K at 6144 context). Runs on a 6GB card, or CPU. |
| RAM | ~2.5 GB for the 195k-title catalog index |
| Disk | ~3.3 GB model + ~240 MB catalog + ~300 MB embeddings |
| Latency | ~1s per request on an RTX 3060; cached responses are instant |
Quickstart
marquee serve --library catalog.jsonl --port 8080
That's the whole setup -- catalog and embeddings ship precomputed.
API
POST /recommend
curl -X POST localhost:8080/recommend -H 'Content-Type: application/json' \
-d '{"title": "The Sopranos", "row_size": 20}'
{
"seed": {"id": "wd:Q23628", "title": "The Sopranos", "year": 1999,
"media_type": "tv", "rating": 0.0, "owned": true},
"rows": [
{"type": "thematic", "title": "Shows like The Sopranos",
"items": [
{"id": "wd:Q...", "title": "Gomorrah", "year": 2014,
"media_type": "tv", "owned": true},
{"id": "wd:Q...", "title": "Boardwalk Empire", "year": 2010,
"media_type": "tv", "owned": true}
]},
{"type": "director", "title": "More from Tim Van Patten",
"items": [
{"id": "wd:Q...", "title": "Game of Thrones", "year": 2011,
"media_type": "tv", "owned": true}
]}
]
}
Body: seed_id or title, plus optional year, media_type, row_size,
owned_only, semantic_k. Rows arrive in a fixed order -- thematic, franchise,
director, cast, crew.
An ambiguous title returns 409 with the candidates rather than guessing. A catalog this size holds many remakes sharing a bare title:
{"error": "22 items match 'Macbeth'; pass seed_id, or narrow with year/media_type",
"matches": [
{"id": "wd:Q15934383", "title": "Macbeth", "year": 2015, "media_type": "movie"},
{"id": "wd:Q2573008", "title": "Macbeth", "year": 1951, "media_type": "movie"}
]}
{"title": "Macbeth", "year": 2015} or {"title": "Macbeth (2015)"} resolves it.
GET /metadata and POST /metadata/batch
Full catalog record for one item, or up to 500 in one call. Pure index lookups -- no
model, no GPU. Look up by id, tmdb_id, imdb_id (all exact), or title (fuzzy,
can be ambiguous like /recommend).
curl 'localhost:8080/metadata?tmdb_id=335984'
{
"id": "wd:Q21500755", "title": "Blade Runner 2049", "media_type": "movie",
"year": 2017, "genres": ["cyberpunk", "dystopian film", "neo-noir"],
"people": [{"name": "Denis Villeneuve", "role": "director"},
{"name": "Roger Deakins", "role": "cinematographer"}],
"summary": "Blade Runner 2049 is a 2017 American science fiction film...",
"franchise": "Blade Runner", "runtime_min": 164,
"country": "United Kingdom", "language": "English",
"external": {"wikidata": "Q21500755", "tmdb": "335984", "imdb": "tt1856101"}
}
curl -X POST localhost:8080/metadata/batch -H 'Content-Type: application/json' -d '{
"queries": [{"tmdb_id": 335984}, {"imdb_id": "tt0141842"}]
}'
Every query gets a result in the order sent -- found, ambiguous with candidates, or not found -- so you can zip the response against your input.
GET /search?q= and GET /person?name=
/search matches titles and people in one call -- "Scorsese" isn't a title but has
109 credits. /person returns everything someone worked on, films and shows together,
ranked by a popularity-weighted score, deduplicated across roles. Both are index
lookups, no model call.
curl 'localhost:8080/person?name=Roger%20Deakins&limit=3'
{"person": "Roger Deakins", "count": 3, "credits": [
{"id": "wd:...", "title": "The Shawshank Redemption", "year": 1994,
"score": 8.66, "roles": ["cinematographer"]}
]}
score is what ranking actually uses -- popularity-weighted, so a well-known film
outranks an obscure one even without a raw rating to sort by.
GET /health and DELETE /cache
{"status": "ok", "contract_version": 1,
"model_self_test": {"passed": true, "detail": "contract v1 OK (3/3 clean)"},
"library_items": 194509, "owned": 194509, "requestable": 0}
status is degraded if the self-test fails -- model and package disagree, or the
chat template is wrong. Recommendations are cached per seed; call DELETE /cache
after a library rescan or you'll serve rows referring to items you no longer have.
Restricting results to your own library (optional)
By default it recommends from the whole catalog. To mark what's actually on your server, so a UI can show a Request button on the rest:
marquee ingest --server library.jsonl --catalog catalog.jsonl \
--out lib.jsonl --mode requestable
marquee serve --library lib.jsonl
Your export needs one line per item; tmdb_id and media_type are enough:
{"id": "myserver-04471", "tmdb_id": 335984, "media_type": "movie"}
Evaluation
50 unseen holdout examples, run through plain transformers.generate with no
grammar constraint, on the unmerged adapter -- so this measures the weights, not a
decoder forcing shape, and not the quantization the GGUF ships with.
| Metric | Base Qwen3-4B | Marquee |
|---|---|---|
| JSON parses | -- | 100% |
| Fully contract-clean | -- | 100% |
| Hallucinated ids | -- | 0.0% |
| Row-order violations | -- | 0% |
That number does not carry over unchanged to the shipped GGUF: merging a LoRA adapter and quantizing it are both lossy steps this harness doesn't exercise. Measured end-to-end through actual Ollama serving (20 held-out seeds, real greedy decoding) -- Q6_K: 19/20 clean. See Limitations below for what pushed us to Q6_K over a smaller quant.
What this is, honestly: the fine-tune buys format discipline, not taste. The retriever picks every item; the model decides which rows to show and writes one row title. It does not make recommendations smarter on its own -- that lives in the retriever's embeddings and joins.
Training
- Base: Qwen3-4B-Instruct-2507, full-precision LoRA (bf16 base, not QLoRA) r=16, lr 2e-4, 1 epoch, 3,684 examples
- Data: generated by Qwen3-8B-AWQ over the catalog below, normalised by a deterministic repair pass. 0.4% rejected.
- Hardware: one RTX 3060 12GB, ~2h48m, 10.2 GB peak VRAM
- Targets are ~30 tokens: the model emits index references, not item lists
- Why full precision, not QLoRA: a QLoRA adapter is calibrated against its 4-bit
base's numerical behaviour. Merging it into full-precision weights for GGUF export
bakes in a dequantized representation the adapter never saw, which destabilized this
model badly enough to periodically emit
<tool_call>instead of JSON. Training directly on real bf16 weights removes that mismatch.
Limitations
- Thematic rows are the weakest part. Built from
bge-smallembeddings blended with keyword and genre overlap; ~31% of the catalog has no plot summary to embed, so those titles lean on genre/subject tags alone. - Franchise coverage is thin (~2%) compared to a TMDB-sourced catalog -- series membership is sparse in the source data.
- Same-medium only. A show returns shows, a film returns films.
- Library-size sensitive. A director with one other credit present gets no row. Deliberate -- no padding.
- Movies and TV only. English metadata.
- No poster/image data. The catalog is text and structured facts only; nothing in
it or the API returns image URLs. Pull artwork from your media server, or from
TMDB/Fanart yourself using the
external.tmdb/external.imdbids in/metadata.
โ ๏ธ GGUF: the chat template is not optional
Ollama will not use the Jinja template embedded in GGUF metadata and falls back to a
bare {{ .Prompt }} passthrough, so the model never receives the <|im_start|>
markers it was trained on and reverts to base-model behaviour. The supplied
Modelfile carries an explicit ChatML TEMPLATE block. Do not remove it.
Two things degrade output independently, and both are already handled in the shipped Modelfile/GGUF:
temperaturemust stay low -- 0.1 gave 8/8 clean over 8 test seeds without a grammar, 0.3 gave 5/8. The Modelfile ships 0.1.- Don't requantize below Q6_K. llama.cpp's Q4_K_M rounding alone -- independent of
temperature, independent of the LoRA-merge issue above -- was enough to collapse
this model into repeating
<tool_call>tokens instead of JSON on most requests (1/20 clean vs Q6_K's 19/20, same weights, same greedy decoding, only the quant level changed). Q6_K is the smallest quant confirmed clean.
Verify any deployment by calling it without a JSON schema. A working fine-tune
emits valid contract JSON unprompted. marquee serve runs this check at startup.
Data
The catalog is built entirely from Wikidata (CC0) and Wikipedia (plot summaries, embedded then discarded -- never redistributed as text, so CC BY-SA's share-alike terms are never triggered). No TMDB data is shipped or was used in training.
Not used: TMDB (API terms prohibit ML training and third-party redistribution of cached content), IMDb (non-transferable, non-sublicensable licence), Rotten Tomatoes (no public API).
Licence
Apache-2.0, inherited from Qwen3-4B-Instruct-2507. Catalog: CC0.
- Downloads last month
- 10
6-bit
Model tree for KernelMedia/marquee-ai
Base model
Qwen/Qwen3-4B-Instruct-2507