SAVRN
Search Contact SAVRN

Open-weight model · Text generation

Janus-35B-HERETIC

by Fool FoolDev/Janus-35B-HERETIC

Architecture: Qwen 3.6 35B-A3B (MoE) | Total Params: ~34.7B | Active Params: ~3B | Context: 262,144 native / 1,010,000 extensible | Base: Heretic (llmfan46) | Teacher: Claude Fable 5 | Type: Distilled + Abliterated MoE LLM A personal fork of…

Parameters
Context
Weights21.2 GB
Licenseapache-2.0
AccessOpen weights
Monthly Downloads421

Model Card

By Fool, published under apache-2.0, revision be7f5279e318.

Architecture: Qwen 3.6 35B-A3B (MoE) | Total Params: ~34.7B | Active Params: ~3B | Context: 262,144 native / 1,010,000 extensible | Base: Heretic (llmfan46) | Teacher: Claude Fable 5 | Type: Distilled + Abliterated MoE LLM A personal fork of llmfan46/Qwen3.6-35B-A3B-uncensored-heretic — an uncensored Heretic-style abliteration of Qwen/Qwen3.6-35B-A3B, the 35B-total / 3B-active mixture-of-experts multimodal base — repackaged as Janus-35B with Claude Fable 5 reasoning data in the teacher slot. Refusal-trained behavior is dialed back at the base layer. One-liner via Hugging Face (pulls a GGUF + this repo's root-level template / system / params files, including the tool-calling template — HF's…

Read Fool's full model card

Janus-35B

Flagship Reasoning. Sparse Footprint. Uncensored. llmfan46's Heretic abliteration of Qwen 3.6 35B-A3B, repackaged with Claude Fable 5 in the teacher slot.

Architecture: Qwen 3.6 35B-A3B (MoE) | Total Params: ~34.7B | Active Params: ~3B | Context: 262,144 native / 1,010,000 extensible | Base: Heretic (llmfan46) | Teacher: Claude Fable 5 | Type: Distilled + Abliterated MoE LLM

A personal fork of llmfan46/Qwen3.6-35B-A3B-uncensored-heretic — an uncensored Heretic-style abliteration of Qwen/Qwen3.6-35B-A3B, the 35B-total / 3B-active mixture-of-experts multimodal base — repackaged as Janus-35B with Claude Fable 5 reasoning data in the teacher slot. Refusal-trained behavior is dialed back at the base layer.

Provenance. This repo repackages — no training and no quantization is performed here. What ships is llmfan46's own Q4_K_M of llmfan46/Qwen3.6-35B-A3B-uncensored-heretic, byte-for-byte, with this repo's Ollama wrapper around it. The Teacher: field above and the datasets: list in the frontmatter are carried over from earlier revisions of this card. The current base does not claim them — its card lists no datasets and names no teacher — and nothing in this repo reproduces or measures them. One listed dataset, Crownelius/Opus-4.7-Reasoning, is not publicly reachable: the Hub answers 401, as it does for a private or missing repo. Treat them as unverified attribution, not as a training record. base_model_relation is quantized for the same reason.

On the repo name: the model is Janus-35B and the Hub slug FoolDev/Janus-35B-HERETIC names it correctly again. Every URL and ollama run hf.co/… pull below is unchanged, as is the Ollama tag (janus).

The base moved three times on 2026-09-18, so the CHANGELOG reads as a round trip: 0.7.0 restored this MoE, 0.8.0 swapped to a dense Qwen 3.8 27B for the newer Qwen generation, and 0.9.0 came back here — Qwen 3.8 ships no 35B-A3B at all, so the choice was 35B or 3.8, and 35B won. If you pulled on that day you may hold either model; ollama pull again to match this card. The dense 27B blob is no longer published and remains in git history.

TL;DR

One-liner via Hugging Face (pulls a GGUF + this repo's root-level template / system / params files, including the tool-calling template — HF's Ollama bridge ingests those three files, not Modelfile):

ollama run hf.co/FoolDev/Janus-35B-HERETIC               # default tag, Q4_K_M
ollama run hf.co/FoolDev/Janus-35B-HERETIC:Q4_K_M        # same blob, explicit tag

Or build locally (uses this repo's Modelfile, kept in sync with the three bridge files):

git clone https://huggingface.co/FoolDev/Janus-35B-HERETIC && cd Janus-35B-HERETIC
ollama create janus -f Modelfile && ollama run janus

After either path, ollama show janus lists completion, tools, and thinking under Capabilities. Hardware: the default num_ctx is the full 262,144 native window — about 25 GiB with Ollama's default f16 KV cache and about 23.0 GiB with OLLAMA_KV_CACHE_TYPE=q8_0. Those totals extrapolate a KV cache measured on this blob on 2026-09-18 (see Hardware requirements). Lower num_ctx on a smaller host (65536 measured at 21.6 GiB), or raise it to 1,010,000 with YaRN (not baked in, so context past ~262K degrades).

To halve the KV cache, start the Ollama server with the q8_0 cache and flash attention (for a systemd install, add them as Environment= lines with sudo systemctl edit ollama):

OLLAMA_KV_CACHE_TYPE=q8_0 OLLAMA_FLASH_ATTENTION=1 ollama serve

What's here

File Use
Janus-35B-A3B.Q4_K_M.gguf Recommended default, 21.23 GB. Upstream's Q4_K_M byte-for-byte — no re-quantization and no MTP strip needed (see Architecture).
Modelfile Ollama wrapper for local builds (ollama create janus -f Modelfile) — carries the Go template that Ollama runs in preference to the GGUF's embedded one (see Which template Ollama runs).
template, system, params Used by HF's Ollama bridge when users ollama run hf.co/FoolDev/Janus-35B-HERETIC directly. The bridge does not read Modelfile (see HF Ollama docs); it ingests these three root-level files instead. Kept in sync with the Modelfile's TEMPLATE / SYSTEM / PARAMETER directives.
scripts/build.sh Pulls a GGUF from llmfan46/Qwen3.6-35B-A3B-uncensored-heretic-GGUF (default Q4_K_M), runs it through strip_mtp.py (a no-op for these quants, kept as a guard), then runs ollama create janus. Quants published there: BF16, Q3_K_L, Q3_K_M, Q4_K_M, Q4_K_S, Q5_K_M, Q5_K_S, Q6_K, Q8_0. The bundled Q4_K_M is that repo's Q4_K_M; use this to build the others locally.
scripts/check_bridge_sync.py Run before pushing a Modelfile / template / system / params edit to verify the four configurations remain in sync. Exits 0 if in sync, 1 with a per-key diff if not.
scripts/check.sh Local lint: bash -n, shellcheck, py_compile, footgun-grep, Modelfile-vs-bridge-files sync and the Go template guard (make check)
scripts/check_go_template.py Guards the Go template: Ollama's thinking detection, the condition that replays earlier turns' reasoning, the tool round trip, JSON tool signatures, and the reasoning-effort mapping — the xhigh and low arms and the medium/unset default (check 8 in check.sh)
scripts/live_check.sh Live end-to-end checks in an isolated, CPU-only Ollama (own port and model store; it refuses to run if Ollama reports a GPU): template selection, one tool call, string-argument replay, an earlier turn's reasoning replayed and a live tool chain's kept, every reasoning_effort value and the effort lines — 17 checks (make live-check)
scripts/verify_arch.py Cross-checks the README Architecture bullets (layer count, hidden size, expert counts and widths, native context, vocab) plus the underlying forward-pass structure (Gated Attention + Gated DeltaNet dims, partial RoPE, full-attention interval) against the bundled GGUF's qwen35moe metadata. Run on demand (python3 scripts/verify_arch.py); reads the 21 GB GGUF (LFS smudge required) and exits non-zero on any mismatch. block_count is checked against 40, this model's natural depth — the MTP-Preserved variant this repo does not ship reports 41.
scripts/strip_mtp.py Drops an MTP / NextN layer from a Qwen 3.x GGUF (python3 scripts/strip_mtp.py IN.gguf OUT.gguf): removes the extra blk.<last>.* block, decrements block_count, drops nextn_predict_layers. Kept tensors are copied byte-for-byte (no re-quant); a conditional no-op (hardlink) on already-clean quants — which is what it is for the quants this repo ships, since llmfan46's plain …-heretic-GGUF files carry no NextN block. It stays in the build path as a guard for anyone pointing build.sh at the …-Native-MTP-Preserved-GGUF variant instead. Parity with the dense sibling FoolDev/Thanatos-27B-HERETIC, where the strip is required.
scripts/smoke_test.sh Integration smoke test against a running Ollama daemon: server reachable, model loaded, tools capability present, chat round-trip, and no control-token leakage. TOOLS_TEST=1 adds a tool-call round-trip. Defaults to MODEL=janus.
scripts/bench.sh Measures tok/s from Ollama's eval_count / eval_duration over a short/medium/long prompt mix (with a discarded warmup). Defaults to MODEL=janus.
scripts/load_bundle.sh Loads the bundled Janus-35B-A3B.Q4_K_M.gguf into Ollama as a local janus tag without an upstream pull (if the working-tree file is still an LFS pointer it downloads the real blob into .cache/ — it does not smudge in place — then checks the arch is qwen35moe).
scripts/cap_ctx.sh Bakes a small-num_ctx local janus tag (bundled blob + this repo's Modelfile, num_ctx→4096, num_batch 256) for OpenAI /v1 clients — which can't override the baked num_ctx and OOM on small hosts (see Inference examples). Run ./scripts/cap_ctx.sh (or CTX=8192 ...).
scripts/fetch_vision.sh Downloads the vision projector (Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf, 902 MB) from the Heretic GGUF repo for llama.cpp image input (Ollama vision is broken upstream — see Vision).
examples/ Ready-to-run Python clients for Ollama, Transformers, and llama-cpp-python (text, tools, and vision — see examples/README.md)

GGUF-only release. Pull the Heretic safetensors from llmfan46/Qwen3.6-35B-A3B-uncensored-heretic if you need the transformers tree (or the vanilla pre-Heretic base from Qwen/Qwen3.6-35B-A3B). The safetensors also keep the MTP layer that this GGUF does not carry — that's the path to speculative decoding under vLLM / SGLang.

Bundled blob status: the 35B-A3B MoE is published

The bundled GGUF is Janus-35B-A3B.Q4_K_M.gguf (21,233,608,512 bytes — 21.23 GB decimal, 19.78 GiB binary) — the Qwen 3.6 35B-A3B MoE this card describes. ollama run hf.co/FoolDev/Janus-35B-HERETIC serves it directly, and ollama create janus -f Modelfile works from a fresh clone.

It is llmfan46/Qwen3.6-35B-A3B-uncensored-heretic-GGUF's Q4_K_M (sha256 b82f9f2155eb9c07139d48cc3a37880cf9d0edcca345ef6ad829b62941ccbb82) byte-for-byte: no re-quantization, no MTP strip and no template restamp. This quant carries no NextN block to strip, and the GGUF keeps the base model's own embedded chat template — this repo ships no chat_template.jinja of its own.

Verified before publishing (2026-09-18): the file's GGUF header was read directly from the published blob by HTTP range request — general.architecture qwen35moe, block_count 40, 256 experts / 8 active, context_length 262144, vocab 248,320, 733 tensors, no nextn key and no NextN tensors — and every Architecture claim below matches it. scripts/live_check.sh was then run against this blob on 2026-09-18 — Ollama 0.33.3, isolated store, CPU only — and all 17 live checks passed: the model loaded, Ollama selected the Go template with thinking detected, a first-turn tool call came back exactly once, a replayed tool result with JSON-string arguments was answered, reasoning replayed across turns and inside a live tool chain, and every reasoning_effort value returned 200 with the tiers reaching the prompt. What is still unmeasured on this blob: the runtime memory figures (weights, recurrent state, compute buffer) and any throughput number.

Between 0.2.0 and 0.6.5 this repo shipped a dense Qwen 3.8 27B (Janus-27B.Q4_K_M.gguf). That blob is no longer published; it remains in git history.

Architecture

A sparse hybrid stack: linear-attention (Gated DeltaNet) layers with a full Gated Attention layer every fourth block, and a 256-expert MoE feed-forward on every block. ~34.7B parameters total, ~3B active per token — 8 routed experts plus one shared expert.

  • Qwen 3.6, 35B-A3B mixture-of-experts (256 experts, 8 routed per token, plus a shared expert on every block)
  • 40 layers, 10 × (3 × Gated DeltaNet → MoE / 1 × Gated Attention → MoE) — full_attention_interval 4, so 10 full-attention and 30 linear-attention layers
  • Hidden size 2048; per-expert FFN intermediate 512, shared-expert FFN 512
  • Gated Attention: 16 Q-heads / 2 KV-heads (GQA), head_dim 256, gated output projection, partial RoPE (rope.dimension_count 64 of 256 dims rotated), rope.freq_base 1e7
  • Gated DeltaNet: conv kernel 4, state size 128, 16 groups, inner size 4096
  • 262 144 native context (extensible to 1 010 000 with YaRN, but YaRN is not enabled in the bundled GGUF)
  • Vision + video supported by upstream (mmproj not included in this release — see Vision)
  • Vocab 248,320
  • GGUF arch stamp qwen35moe — the MoE arch in llama.cpp (src/models/qwen35moe.cpp, case 40: LLM_TYPE_35B_A3B); the dense members of the family stamp qwen35

Every bullet above is asserted against the bundled GGUF's own metadata by python3 scripts/verify_arch.py.

MTP head (absent from this quant). The base does declare an MTP layer (mtp_num_hidden_layers: 1 in its config.json) for vLLM / SGLang speculative decoding, but the Q4_K_M published in llmfan46's GGUF repo — the file this repo bundles — carries no NextN block: block_count is 40 and blk.0blk.39 are all that exist. So no strip is needed here, and scripts/strip_mtp.py is a defensive no-op on it. llmfan46 also publishes a separate …-Native-MTP-Preserved-GGUF variant whose Q4_K_M has block_count 41 with a NextN block at index 40; that one would need stripping, and it is not what this repo ships. For the MTP head itself, run the upstream safetensors under vLLM / SGLang.

Quick start

llama.cpp / LM Studio

Drop the GGUF into your loader of choice. The chat template is embedded in the GGUF metadata, and llama.cpp and LM Studio use it by default, so no --chat-template flag is needed (llama.cpp has no --chat-template auto mode; it would take "auto" as the template itself).

Tool calling works out of the box — the GGUF carries Qwen 3.6's own template, so --jinja alone is enough and there is no file to pass:

llama-server -m Janus-35B-A3B.Q4_K_M.gguf --jinja

Tool calls use Qwen's native XML form, the one llama-server's parser reads. Two things this path does not have, because they lived in the patched Qwen 3.8 template this repo shipped between 0.2.0 and 0.6.5 and no longer ships: reasoning_effort tiers, and the tool_call_format JSON opt-in. See Tool / function calling and Reasoning effort.

Ollama

Ollama chooses between the GGUF's embedded template and a Go template at load time (see Which template Ollama runs); this repo ships a Go template so Ollama keeps its JSON tool-call format. Two paths deliver it:

# A. Pull straight from HF (uses the root-level template/system/params files):
ollama run hf.co/FoolDev/Janus-35B-HERETIC               # default tag, Q4_K_M
ollama run hf.co/FoolDev/Janus-35B-HERETIC:Q4_K_M        # same blob, explicit tag
# Note: HF's Ollama bridge does NOT read Modelfile; it reads template/system/params.

# B. Build locally (uses Modelfile, which is kept in sync with the three above):
ollama create janus -f Modelfile && ollama run janus

After the local build (path B), ollama show janus lists completion, tools, and thinking under Capabilities. (The HF-pull paths register the model under the full tag hf.co/FoolDev/Janus-35B-HERETIC, not janus.)

Inference examples

Once the model is loaded (via ollama run janus, lms server, or llama-server), all the standard OpenAI-compatible clients work. Examples assume the loader is listening on http://localhost:11434 (Ollama default) — adjust the port for LM Studio (:1234) or llama.cpp (:8080). Runnable versions of everything below live in examples/.

The examples use model: "janus", the tag from the local build (path B). If you pulled via the TL;DR one-liner instead, use the full tag hf.co/FoolDev/Janus-35B-HERETIC, or run ollama cp hf.co/FoolDev/Janus-35B-HERETIC janus once to create the short tag.

On memory-tight hosts, cap num_ctx first. /v1/chat/completions (OpenAI-compat) has no num_ctx knob, so it loads at the baked 262,144 default (5.0 GiB KV / ~25.4 GiB total with Ollama's default f16 cache), which is tight on a 32 GB box; OLLAMA_KV_CACHE_TYPE=q8_0 on the server brings it to ~23.0 GiB. For an OpenAI /v1 client the fix is a tag baked at a smaller context, and ./scripts/cap_ctx.sh does exactly that in one step: it creates a local janus tag from the bundled blob and this repo's Modelfile with num_ctx 4096 and num_batch 256 (CTX=8192 TAG=janus-cap ./scripts/cap_ctx.sh to change either). Callers that can send Ollama's own options field — /api/chat, not /v1 — pass those same two values per request instead; see Hardware requirements for that recipe and the full memory table.

curl
curl -s http://localhost:11434/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "janus",
    "messages": [
      {"role": "system", "content": "You are Janus, a precise reasoning assistant."},
      {"role": "user", "content": "Sketch an algorithm to detect cycles in a directed graph."}
    ],
    "temperature": 0.6,
    "max_tokens": 800
  }' | jq -r '.choices[0].message.content'
Python (openai-compat)
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ignored")

resp = client.chat.completions.create(
    model="janus",
    messages=[
        {"role": "user", "content": "Write a haiku about a stack overflow."}
    ],
    temperature=0.8,
    top_p=0.95,
)
print(resp.choices[0].message.content)
Streaming
stream = client.chat.completions.create(
    model="janus",
    messages=[{"role": "user", "content": "Explain RoPE briefly."}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="", flush=True)

Recommended sampling

Use temp top_p top_k repeat_penalty
Default (Fable-matched) 1.0 0.95 0 1.05
Tighter reasoning 0.6 0.95 20 1.05
Creative / RP 0.8 0.95 40 1.02

The shipped default is Fable-matched — warm (temperature 1.0), no top_k, with top_p 0.95 + repeat_penalty 1.05 kept as loop insurance. Drop to the reasoning row for tighter, more deterministic output; lower temperature (0.4–0.6) and bump repeat_penalty to 1.08 if it loops inside <think> tags.

top_p does not survive the OpenAI-compatible endpoint. Ollama's /v1/chat/completions layer applies OpenAI's own default of top_p 1.0, overwriting the 0.95 baked into params / the Modelfile. Measured on this model: the same request logs top_p = 0.950 on /api/chat and top_p = 1.000 on /v1/chat/completions. Since the default profile also sets top_k 0 (disabled), a /v1 request samples with no truncation at all at temperature 1.0 — the "loop insurance" above is only in effect on the native API. If you need that guard on /v1, send top_p explicitly on every request, or bake min_p (e.g. PARAMETER min_p 0.05) into a local tag — min_p and top_k both pass through /v1 untouched, top_p does not.

System prompt

You are Janus, a precise and capable assistant for reasoning, writing, coding, and long-form dialogue.

Behavior rules:
- Answer the user's actual request directly.
- Be accurate, complete, and structured.
- Think before answering, but do not get stuck in repetitive loops or meta-commentary.
- If the request is ambiguous or incomplete, state what is missing and make the smallest reasonable assumption needed to continue.
- If the user wants creative writing, preserve tone, continuity, and character consistency.
- If the user wants analysis or technical help, prefer concrete steps, examples, and decisions over fluff.
- Finish with a usable answer, not just planning.

Vision

The Qwen 3.6 base supports image (and video) input via a separate mmproj projector. The full multimodal stack is:

Janus-35B-A3B.Q4_K_M.gguf                            (21.23 GB, the text decoder)
Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf  (902 MB, the vision projector)

The projector and other-quant text decoders live at llmfan46/Qwen3.6-35B-A3B-uncensored-heretic-GGUF (BF16 mmproj only). This repo intentionally does not redistribute it; ./scripts/fetch_vision.sh pulls the projector into the repo root.

Loader compatibility

Loader Text Vision (mmproj) Notes
llama.cpp (llama-mtmd-cli, llama-server --mmproj) Yes Yes Reference path. Upstream has the qwen35moe arch entry (src/models/qwen35moe.cpp).
llama-cpp-python Yes Yes See examples/llama_cpp_vision.py.
Ollama (0.33.3 and 0.34.x checked in source, 2026-09-18) Yes No Text inference works: qwen35moe is handled through Ollama's llama.cpp compat shim at v0.33.3, v0.34.0 and v0.34.2. The version floor this row used to claim ("0.24+") was undated and inherited from the MoE-era card; it has not been re-established, so treat these three as the tested set. Vision (mmproj) is still broken: the C++ llama.cpp fallback that Ollama switches to when an mmproj is attached lacks it. ollama create accepts a dual-FROM (text + mmproj) and ollama show reports vision capability — but the first inference request fails with an unknown model architecture load error, and once mmproj is attached this blocks text inference too. See ollama/ollama#14575 (closed as completed on 2026-08-04; #15898 was closed as its duplicate and the sync PR #15899 closed unmerged). Re-test on a current Ollama before assuming vision is still broken — this table has not been re-verified since it closed.
LM Studio Yes Yes Uses upstream llama.cpp directly.

Vision via llama.cpp

# Fetch the projector first (into the repo root):
./scripts/fetch_vision.sh   # Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf

# A. HTTP via llama-server (the easiest path):
llama-server \
  -m Janus-35B-A3B.Q4_K_M.gguf \
  --mmproj Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf \
  --host 127.0.0.1 --port 8765 -c 8192 -ngl 99
# then POST OpenAI-style chat completions with an image_url content block —
# e.g. {"type":"image_url","image_url":{"url":"data:image/jpeg;base64,..."}}
# The thinking trace arrives in message.reasoning_content; the visible
# answer is in message.content. Budget ≥500 max_tokens so the reasoning
# block doesn't crowd out the final answer.

# B. CLI via llama-mtmd-cli (one-shot). It's a separate cmake target, so a
#    selective build can skip it; a plain `cmake --build build` produces it.
llama-mtmd-cli \
  -m Janus-35B-A3B.Q4_K_M.gguf \
  --mmproj Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf \
  --image photo.jpg \
  -p "Describe this image."

# C. Python via llama-cpp-python:
python examples/llama_cpp_vision.py \
  --gguf Janus-35B-A3B.Q4_K_M.gguf \
  --mmproj Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf \
  --image /path/to/photo.jpg \
  --prompt "What is in this image?"

The Ollama issue is closed upstream but this table has not been re-verified since; until you have re-tested, treat Ollama as text-only for this model. The bundled Q4_K_M decoder pairs with the projector directly — the mmproj is family-wide for Qwen 3.6 35B-A3B, so no separate text download is needed for vision.

Hardware requirements

This is a 21.23 GB Q4_K_M GGUF. Measured on 2026-09-18 on Ollama 0.33.3's CPU backend, from llama.cpp's own allocation lines, in an isolated store at num_ctx 8192, 32768 and 65536:

component measured scales with num_ctx?
Weights 19.77 GiB (CPU model buffer 5361.34 MiB + CPU_REPACK 14878.12 MiB) no
Recurrent state (30 Gated-DeltaNet layers) 62.81 MiB — R (f32) 2.81 + S (f32) 60.00 no — identical at every context
KV cache, f16 (Ollama's default) 20,480 B/token → 160 / 640 / 1280 MiB at 8K / 32K / 64K yes, exactly linear
KV cache, q8_0 10,880 B/token → 340 / 680 MiB at 32K / 64K yes, exactly linear
Compute buffer 160.04 / 208.04 / 544.07 MiB at 8K / 32K / 64K yes, but not linearly

The KV cache covers only the 10 full-attention layers (llama.cpp logs it as "10 layers", 2 KV heads × 256 key + 256 value dims), which is under a third of the dense 27B's 2 GiB per 32K at the same window — the single biggest difference between the two siblings. q8_0 needs OLLAMA_KV_CACHE_TYPE=q8_0 with OLLAMA_FLASH_ATTENTION=1; flash attention is otherwise auto.

num_ctx f16 cache (default) q8_0 cache
262144 (default) 5.0 GiB KV, ~25.4 GiB total 2.66 GiB KV, ~23.0 GiB total
65536 1.25 GiB KV, 21.6 GiB total (measured) 0.66 GiB KV, 21.0 GiB total (measured)
32768 0.63 GiB KV, 20.7 GiB total (measured) 0.33 GiB KV, 20.4 GiB total (measured)
1010000 (needs YaRN) 19.3 GiB KV, ~39.6 GiB total 10.2 GiB KV, ~30.5 GiB total

The 32768 and 65536 rows are sums of measured parts. The 262144 and 1010000 rows extrapolate the KV cache — exact, since it is linear in num_ctx — and carry the compute buffer forward from 65536, the largest context measured; the compute buffer grows faster than linearly between 32K and 64K, so treat those two rows as floors. It's extensible to 1,010,000, but this GGUF ships no baked YaRN rope-scaling, so positions past the 262144 native window use untrained RoPE and output degrades — reaching the 1.01M ceiling needs YaRN (see below); keep real work within ~262K otherwise.

How to override it: ollama run has no -o flag, and OLLAMA_CONTEXT_LENGTH only sets a default that the baked num_ctx overrides — so set it per-session from the interactive prompt. The model loads lazily on the first message, so /set applies before the default context is allocated:

ollama run hf.co/FoolDev/Janus-35B-HERETIC:Q4_K_M
>>> /set parameter num_ctx 4096
>>> /set parameter num_batch 256

Programmatic callers pass the same via the API options field: "options": {"num_ctx": 4096, "num_batch": 256} — but only on Ollama's own /api/chat. /v1/chat/completions ignores options entirely, so an OpenAI-compatible client needs a tag baked at the smaller context instead: ./scripts/cap_ctx.sh bakes one with those same two values, from the bundled blob and this repo's Modelfile.

Hardware Status
≥48 GB RAM (CPU-only) Works at the 262144 default (~25.4 GiB) with room to spare
Single H100/A100 80 GB Works, full offload
RTX 4090 24 GB / 5090 32 GB + 32 GB RAM Works, partial offload
Mac Studio M2/M3 Ultra 64 GB+ unified Works
32 GB unified-memory laptops (Ryzen AI Max+, Apple M-series) ~25.4 GiB at the 262144 default leaves little headroom on a 27 GiB-visible host; OLLAMA_KV_CACHE_TYPE=q8_0 (~23.0 GiB) or num_ctx 65536 (21.6 GiB measured) is the comfortable setting

Throughput, measured on CPU only: ~25 tok/s. On a Ryzen AI Max+ 395 with Ollama 0.33.3's CPU backend, in an isolated store, ./scripts/bench.sh measured an aggregate of 24.97 tok/s (4,543 generated tokens over 181,890 ms) across its three-prompt mix after a discarded warmup — 25.88, 25.57 and 24.87 tok/s individually, so the rate barely moves with output length. Timings come from Ollama's own eval_count / eval_duration, not a client stopwatch. Switching the server to OLLAMA_KV_CACHE_TYPE=q8_0 with OLLAMA_FLASH_ATTENTION=1 made no meaningful difference to generation speed — 24.85 tok/s aggregate over the same mix, 0.5% below the f16 run. It buys memory, not speed.

That is about five times the 4.97 tok/s the dense 27B measured on this same CPU, which is the MoE's ~3B active parameters per token doing exactly what they should. Two caveats worth keeping in mind: this is generation speed, and a reasoning-first model emits a lot of tokens per answer — the third prompt, which asks for a 120-word explanation, produced 3,918 tokens including its <think> block, so wall-clock per answer is longer than the rate alone suggests. Prompt processing is not covered by this number.

GPU offload on a Strix Halo iGPU (Radeon 8060S): a small gain, and a trap. On a Vulkan integrated GPU, llama.cpp - including the build Ollama 0.33.3 bundles - turns mmap off and puts every layer it does not offload into GPU-reachable host memory from the same pool as the GPU, so num_gpu alone does not limit GPU memory: a first attempt with llama-server filled the pool and took the desktop down with it. With LLAMA_ARG_NO_HOST=1 in the Ollama server's environment (llama.cpp's --no-host) those layers stay in ordinary RAM. That mechanism is loader-side and applies to any model; the tok/s series this paragraph used to quote was measured on the dense 27B and has been removed with the rest. What generalises: the GPU's GTT is system RAM, so offloading frees none of it, and a first attempt without --no-host filled the pool and took the desktop session down with it. If you try the GPU on a machine like this, set LLAMA_ARG_NO_HOST=1 and a fixed num_gpu. The mechanism is reported upstream in ggml-org/llama.cpp#27360.

Reaching a coherent ~1.01M context (opt-in YaRN). The bundled GGUF ships no YaRN rope-scaling, so raising num_ctx toward the 1.01M ceiling degrades past the 262144 native window (see above). Ollama has no rope knob, so for a genuinely coherent long context run the GGUF under llama.cpp with YaRN enabled:

llama-server -m Janus-35B-A3B.Q4_K_M.gguf \
  --rope-scaling yarn --yarn-orig-ctx 262144 --rope-scale 3.853 -c 1010000

--rope-scale 3.853 ≈ 1010000 / 262144; use a smaller factor for a smaller window. Static YaRN rescales all prompts, so enable it only when you actually need > 262K — it slightly degrades short-context quality otherwise.

Chat template

The model uses the standard Qwen 3.x ChatML format with <|im_start|> / <|im_end|> role markers. Two templates are in play. The GGUF carries Qwen 3.6's own embedded template, exactly as llmfan46 published it — this repo ships no chat_template.jinja of its own — and that is what llama.cpp, LM Studio and KoboldCpp render. On Ollama the Go template / Modelfile TEMPLATE is what runs instead: Ollama picks between the two at load time (see Which template Ollama runs). Where the two differ, this card says which one it is describing.

Plain conversation

<|im_start|>system
You are Janus, a precise and capable assistant…<|im_end|>
<|im_start|>user
What is the time complexity of mergesort?<|im_end|>
<|im_start|>assistant

With reasoning trace

When the model decides to think, the assistant turn contains a <think>…</think> block followed by the visible answer:

<|im_start|>assistant
<think>
The user is asking about mergesort. Mergesort divides the array, recursively sorts each half, then merges. The recurrence T(n) = 2T(n/2) + O(n) solves to O(n log n).
</think>

Mergesort runs in **O(n log n)** time in the worst, average, and best cases. The recurrence is T(n) = 2T(n/2) + O(n), which solves to Θ(n log n) by the master theorem.<|im_end|>

Most clients (Open WebUI, LibreChat, etc.) hide the <think> block by default and show only the final answer. If your client doesn't, set its "show reasoning" toggle off.

Thinking is replayed across turns

Traces from earlier assistant turns are replayed back into the prompt: every assistant message that carries reasoning renders its <think>…</think> block, so the model can see how it reached its previous answers. The turn in progress — including a tool-call chain, where the model calls a tool and then continues after the result — keeps its own either way. On llama.cpp this is upstream's default; on Ollama it departs from Qwen's stock condition, which kept only the turn in progress.

The client has to send the reasoning back. The server returns it — Ollama's /api/chat in the response's thinking field, llama.cpp in reasoning_content — but only reasoning that arrives in the history's assistant messages is replayed, and each endpoint reads one field:

Endpoint Field read from each assistant message
Ollama /api/chat thinking
Ollama /v1/chat/completions reasoning only — reasoning_content and thinking are dropped silently, and a message whose content is an array of parts keeps its reasoning only if it also has tool_calls
llama-server /v1/chat/completions reasoning_content

Which field each endpoint reads is decided by the server, not the model. Measured on this blob on 2026-09-18 (scripts/live_check.sh, Ollama 0.33.3, isolated store, CPU only): the prior turn's reasoning was replayed on /api/chat at 232 prompt tokens with it against 187 without, and a live tool-call chain kept its own reasoning (375 against 330). The same 232/187 figures were measured on the dense 27B in 0.6.x — unsurprising, since both share the 248,320-token vocabulary and this repo's Go template. The /v1 behaviour (reasoning read at 215 vs 187, reasoning_content ignored at 187, and llama-server rendering reasoning_content while dropping reasoning) was checked on 2026-09-13 on that dense blob; it is server-side and carries over. That Ollama's /v1 also drops thinking, and the array-content rule, come from Ollama's v0.33.3 and v0.34.0 source, and still hold on the current release: openai/openai.go and server/prompt.go are byte-identical from v0.33.3 through v0.34.2 (source, 2026-09-17). Ollama never passes reasoning to the GGUF's embedded Jinja template, so on Ollama only the Go template decides what is replayed. On llama.cpp an earlier assistant turn that carries no reasoning renders with no <think> block at all: Qwen 3.6's template gates the block on reasoning_content|length > 0. The 3.8 template this repo used to ship reconstructed an empty one instead, so prompts built by the two differ on that turn.

The cost is context. Every retained trace stays in the prompt — measured on the dense 27B at 181 prompt tokens without and 464 with, on a 3-message conversation whose first assistant turn carried a ~240-word trace, and not re-measured here. Prefill grows with every retained trace, and on a CPU-only host prefill is the slow part. Releases 0.3.0 through 0.3.2 turned replay off for that reason; the CHANGELOG has the history.

On llama.cpp, Qwen 3.6's own template decides. Read from the template inside the published blob (2026-09-18, from source — not re-tested live on this model): preserve_thinking defaults to true, so an earlier turn's reasoning is replayed by default; the assistant branch takes the trace from message.reasoning_content, and failing that recovers one by splitting a <think> block out of content; and there is no preserve_reasoning variable in it at all. That last point costs nothing, because llama-server derives a preserve_thinking kwarg from preserve_reasoning (common/jinja/caps.cpp), and from b10763 it passes preserve_reasoning=true by default — so --no-reasoning-preserve and a request's preserve_reasoning: false still reach this template through the derived copy, while a request's own preserve_thinking is read directly.

Which llama.cpp an Ollama carries. 0.33.3 and 0.34.0 bundle b10760; 0.34.1 bundles b10864 and 0.34.2 b10969 (each release's LLAMA_CPP_VERSION). From 0.34.1 on that is a b10763-or-later llama-server — the family that passes preserve_reasoning=true by default — but it changes nothing here: text inference for this model runs Ollama's own Go engine, and the bundled llama.cpp comes into play only when Ollama falls back to its C++ engine, as it does once an mmproj is attached (see Loader compatibility).

Nothing raises on conflicting settings. The Qwen 3.8 template that this repo patched between 0.4.0 and 0.6.5 raised when preserve_thinking and preserve_reasoning disagreed, and llama-server returned that raise as HTTP 500 — which is what the patch existed to prevent. Qwen 3.6's template has no such check: it reads preserve_thinking, ignores anything else, and cannot fail that way.

To turn replay off:

  • llama-server — start it with --no-reasoning-preserve, or send "chat_template_kwargs": {"preserve_thinking": false} on a request. A request's preserve_thinking: true switches it back on for that request. {"preserve_reasoning": false} works too, through the kwarg llama-server derives from it; the template itself never reads that name.
  • Ollama — edit the template. In the assistant branch of both the Modelfile and template (so make check's bridge sync stays green), change {{ if (and $.IsThinkSet .Thinking) -}} back to Qwen's stock {{ if (and $.IsThinkSet (and .Thinking (or $last (gt $i $lastUserIdx)))) -}} (keep the -}}; the $lastUserIdx loop at the top of the template is still there for it). Do not delete the block instead — see Which template Ollama runs. make check's Go-template guard will then fail, since it pins the replay condition.

Disabling thinking

This is a reasoning-first model — it opens a <think> block by default. For a direct answer with no reasoning trace (simple or latency-sensitive calls), turn thinking off:

ollama run hf.co/FoolDev/Janus-35B-HERETIC:Q4_K_M --think=false

or send "think": false on /api/chat. With thinking off the model skips the reasoning trace and answers straight into content; with it on (the default) reasoning is emitted into the thinking field.

On llama.cpp the switch is the embedded template's own: send "chat_template_kwargs": {"enable_thinking": false}, which primes a closed, empty <think> block — and, because the template gates its replay branch on enable_thinking too, drops every earlier turn's trace for that request. That variable is upstream Qwen 3.6's, not this repo's.

Reasoning effort

This works on Ollama, and not on llama.cpp. The instruction comes from this repo's Go template, which Ollama runs (see Which template Ollama runs). Qwen 3.6's own template — the one inside the bundled GGUF, and so the one llama.cpp and LM Studio render — has no reasoning_effort variable at all, so there the tier values are accepted by the server and then quietly ignored (read from the template, 2026-09-18). none is the one exception: llama-server maps it to enable_thinking: false and drops the kwarg before the template runs (tools/server/server-common.cpp, checked 2026-09-18), so reasoning_effort: "none" does switch thinking off on llama.cpp. Between 0.2.0 and 0.6.5 this repo shipped a patched Qwen 3.8 template that did implement the tiers on the llama.cpp path; that file is gone with the rebase back to the MoE.

Ollama folds the eight values its /v1 layer accepts into four think levels before any template sees them, so the Go template maps levels, not values:

reasoning_effort (Ollama /v1) Think level Effect
high, xhigh, max, ultra xhigh the model is told to think carefully and check its assumptions
medium, unset, null medium the default; no effort instruction is added
low, minimal low the model is told to keep its thinking brief
none thinking off for that request, the same as "think": false

"think": "high", "low" and "max" on /api/chat map the same way. Mixed case such as "HIGH" is rejected by Ollama itself with HTTP 400 before any template runs. The value-to-level mapping comes from Ollama's source, unchanged from v0.33.3 through v0.34.2 (2026-09-17).

Verified on this blob with scripts/live_check.sh (2026-09-18, Ollama 0.33.3, CPU only): all eight values returned HTTP 200 and none switched thinking off. On a one-line chat the tiers reach the prompt exactly as the table says — unset and medium added no instruction (159 prompt tokens), high and max each added the xhigh instruction (197, so +38), and low added the low instruction (185, +26). The same deltas were measured on the dense 27B in 0.6.x, which is expected: the Go template and Ollama's folding are model-independent.

Which template Ollama runs

Two templates exist for the same ChatML model: the Go template this repo ships (served by HF's Ollama bridge) / Modelfile TEMPLATE, and Qwen 3.6's own template inside the GGUF, which llmfan46 stamped and this repo leaves untouched. They do not render identical prompts — the Go template pins JSON tool calls and adds a reasoning-effort line from Ollama's think level, while the embedded template teaches the XML <function=…> form and has no effort variable at all.

Ollama picks one at load time: it prefers the embedded template when that advertises more capabilities — tools, thinking — and keeps the Go template when they tie. Both advertise tools and thinking, so they tie and Ollama runs the Go template; llama.cpp and LM Studio run the embedded one. Verified live against this blob on 2026-09-18 (scripts/live_check.sh, Ollama 0.33.3): with Qwen 3.6's own template embedded in the GGUF, Ollama still selected the Go template with thinking detected — so the tie holds for the MoE, not just for the dense 27B it was first checked on. The selection code is unchanged through v0.34.2 (source, 2026-09-17). Ollama's built-in renderers — it ships a qwen35 one — displace both templates only when the model's own config names a renderer or parser, which this repo's does not. Ollama logs the choice:

msg="template selection" ... selected=go_template go_template="[completion tools thinking]"

Upstream watch — ollama/ollama#17965. By its own description, that PR ("server: auto-detect ornith and qwen35 renderer and parser") would stamp a qwen3.5 renderer and parser into the config of every qwen35 / qwen35moe model at create time — this one included. That is precisely the condition the paragraph above rests on not holding, so the consequence follows from the rule stated there rather than from any test: were it to land, the built-in renderer would displace both templates, and the JSON tool-call shape and reasoning_effort line documented in this section would stop being what actually runs. Checked 2026-09-18 with gh pr view 17965 -R ollama/ollama: open since 2026-08-24, no approving review, a collaborator disputing the approach in the thread, and the branch conflicting with main — not merged, so nothing here changes yet. If it does merge, re-check the server's template selection log line (and ollama show janus --modelfile) for a named renderer or parser before trusting this section's claims.

The Go template's "thinking" entry comes from its single .Thinking reference — the block that renders each assistant turn's reasoning. Removing it drops that capability, and Ollama switches to the embedded template: tool calls change from JSON-in-XML to Qwen's XML form, which Ollama's extractor does not parse into a tool_calls array, reasoning_effort stops doing anything (the embedded template has no such variable), and a single tool call can come back twice (seen once on the dense 27B under the embedded template; never on the Go-template path, which returned exactly one call on this blob on 2026-09-18 — cause inferred, not confirmed; see Known limitations). Setting OLLAMA_GO_TEMPLATE=1 or =0 on the Ollama server forces one template or the other for every model.

Tool / function calling

The model emits whichever format the prompt specifies, and the two paths specify different ones: the Ollama path pins JSON-in-XML, while the llama.cpp path gets Qwen's native XML form from the template embedded in the GGUF.

Ollama path (this repo's Modelfile). The TEMPLATE advertises tools inside <tools>…</tools> and asks the model to reply in JSON-in-XML — the form Ollama's tool-call extractor parses into a structured tool_calls array on /api/chat and /v1/chat/completions. The tool definitions go in with {{ json .Function }}: on Ollama 0.14 and later a bare {{ .Function }} prints Go struct syntax instead of JSON (ollama/ollama#14601; fix proposed in ollama/ollama#18391). The model replies like this:

<tool_call>
{"name": "get_weather", "arguments": {"city": "Tokyo"}}
</tool_call>

Embedded-template path (llama.cpp, llama-cpp-python, LM Studio, KoboldCpp). The bundled GGUF carries Qwen 3.6's own template, so --jinja alone is enough — there is no file to pass and nothing to stamp. It teaches the XML form:

<tool_call>
<function=get_weather>
<parameter=city>
Tokyo
</parameter>
</function>
</tool_call>

Keep XML on llama-server. llama-server recognises this template as Qwen3-Coder-style and parses the model's reply with a parser — and, once the model opens <tool_call>, a grammar — that accept only <function=…><parameter=…>. Qwen 3.6's tool-instruction literal is byte-identical to Qwen 3.8's (compared 2026-09-18), so the detection and the wire format are exactly what this card documented before the reversal. What is gone is the tool_call_format knob: the JSON opt-in described in releases 0.3.0 through 0.6.5 lived in the patched 3.8 template this repo no longer ships.

Replayed tool calls: normalise arguments first. Every OpenAI-compatible client hands assistant tool calls back with function.arguments as a JSON string, while the XML parameter form needs the individual key/value pairs — a chat template has tojson but no inverse. Qwen 3.6's template renders <parameter=…> only when arguments is a mapping; handed a string it emits that string as-is inside <function=…>, carrying upstream's own comment that you should "normalize arguments to a dict in your serving layer before applying this template". It does not raise, so a loader that passes the string straight through produces a silently malformed prompt rather than an error — the failure is quieter here than it was under the 3.8 template, which raised and returned HTTP 500.

In practice the loaders convert before rendering: llama-server decodes the string into a mapping, KoboldCpp (--jinja --jinja_tools) runs json.loads first, and the LM Studio app parses the arguments before its own JavaScript Jinja engine renders. All three were checked on 2026-09-14 against the 3.8 template this repo shipped then; the conversion is loader-side, so it applies unchanged here (from source for this template — not re-tested on this blob).

Example (Ollama, OpenAI-compatible API)
from openai import OpenAI

client = OpenAI(base_url="http://localhost:11434/v1", api_key="ignored")

resp = client.chat.completions.create(
    model="janus",
    messages=[
        {"role": "user", "content": "Call get_weather for Tokyo. Respond ONLY with the tool call."}
    ],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        },
    }],
    temperature=0.3,
)
print(resp.choices[0].message.tool_calls)
# [ToolCall(id='call_xxx', type='function',
#           function=Function(name='get_weather', arguments='{"city":"Tokyo"}'))]
Tips
  • Use direct prompts ("Call X for Y") rather than soft hints ("Use the tool"). The model thinks before committing to a call, and weak prompts can exhaust num_predict inside the <think> block before the call is emitted.
  • Allow at least num_predict: 1024 (or max_tokens: 1024) for tool-calling turns, more if the schemas are large.
  • The JSON-in-XML format is what Ollama's tool-call extractor understands, and the Go template pins it; the GGUF's embedded template renders the XML <function=…> form. So the prompt format does change when you swap loaders, while client code should not have to, as long as the server returns a parsed tool_calls array.

Known limitations

  • On the embedded-template path, a single tool call can come back twice. Seen on the dense 27B blob, not re-tested here: in one test Ollama 0.33.3, running the embedded template, returned a first-turn tool call twice. A separate raw generation showed the model drafting the call inside <think> before emitting it once after </think>, so the parser most likely matched such a draft (inferred, not confirmed). It did not reproduce on standalone llama.cpp master (a2878d3, CPU): across both models, 12 first-turn calls (three prompts, with and without parallel_tool_calls) and two streamed runs each came back exactly once. Nor on b10760, the llama.cpp build Ollama 0.33.3 bundles and the one the duplicate came through: six more first-turn calls and a streamed run on this model each came back once. LM Studio's CPU engine (llama.cpp b10519) passed the same checks; the LM Studio app's own API layer is untested. Ollama's default path — the Go template, see Which template Ollama runs — returned exactly one call, re-confirmed on this MoE blob on 2026-09-18 (scripts/live_check.sh, first-turn call at reasoning_effort: high, one tool_calls entry). Whether the prompt or the parser makes the difference on the embedded path was not isolated. If your client executes tools wherever the embedded template renders (llama.cpp, LM Studio, or Ollama with OLLAMA_GO_TEMPLATE=0), drop identical consecutive calls.
  • No mmproj in this release. The base Qwen 3.6 35B-A3B supports image and video input via a separate mmproj file, which is not included here. Text-only inference works out of the box; multimodal inference requires fetching Qwen3.6-35B-A3B-uncensored-heretic-mmproj-BF16.gguf (or equivalent) from upstream — run ./scripts/fetch_vision.sh and see Vision for the full path.
  • Quantization-induced quality loss. Q4_K_M is a strong general-purpose quant but does measurably degrade math and code accuracy compared to BF16. If you need maximum quality, run the upstream safetensors on a host with room for the full BF16 weights.
  • No MTP head on the GGUF path. The base declares a multi-token-prediction layer (mtp_num_hidden_layers: 1), but the Q4_K_M published in llmfan46's GGUF repo — the file this repo bundles — carries no NextN block at all (see Architecture). No speculative decoding here: use the upstream safetensors under vLLM / SGLang, or llmfan46's separate …-Native-MTP-Preserved-GGUF variant, if you need it.
  • Sparse compute, dense memory. Only ~3B of ~34.7B parameters are touched per token, but every expert has to be resident: the 19.77 GiB of weights is a floor whatever the routing does, and MoE sparsity buys compute, not RAM. What it does buy on the memory side is a small KV cache — 0.625 GiB per 32K at f16 measured, under a third of a comparable dense stack — so long contexts are unusually cheap here relative to the weights.
  • Thinking traces can loop. Like most reasoning-distilled models, Janus-35B occasionally gets stuck repeating itself inside <think> tags. Mitigations: lower temperature to 0.4-0.6, raise repeat_penalty to 1.08, or set a <think>-token budget cap if your loader supports it.
  • Large tool-call arguments can be dropped. Ollama's JSON-in-XML tool format makes the model JSON-escape the entire arguments object inline; for a big/complex payload (e.g. a file's content in a write_file call) the model can fail to escape it, so the field arrives undefined and the call fails. Qwen's native <function=…><parameter=…> format (raw values, no escaping) was tested as a fix but parses unreliably through Ollama, so the template deliberately keeps JSON-in-XML. Mitigation: write large files in smaller pieces per call.
  • Uncensored base — not aligned with any specific safety policy. This is a personal repackage of an open-weight base whose refusal behavior has been abliterated away (the llmfan46 Heretic base). There is no RLHF refusal layer; the model will attempt most requests, so downstream safety is entirely the operator's responsibility.
  • No formal evaluation in this card. The hardware table and the ~25 tok/s figure are measured on this blob (2026-09-18), but no task benchmarks (MMLU, HumanEval, …) are claimed, and prompt-processing throughput is not measured. If you produce real numbers and want them included, file a PR. No task benchmarks are claimed either. If you produce real numbers (tok/s, MMLU, HumanEval, …) and want them included, file a PR.

Related models

Model Size Notes
llmfan46/Qwen3.6-35B-A3B-uncensored-heretic 35B-A3B MoE Immediate base. Uncensored Heretic abliteration of Qwen 3.6 35B-A3B; transformers-native safetensors, and the only place the MTP layer survives.
llmfan46/Qwen3.6-35B-A3B-uncensored-heretic-GGUF 35B-A3B MoE Heretic GGUFs — BF16, Q3_K_L, Q3_K_M, Q4_K_M, Q4_K_S, Q5_K_M, Q5_K_S, Q6_K, Q8_0, plus the BF16 mmproj. MTP-clean, so they load as-is; the bundled Q4_K_M is this repo's Q4_K_M, byte-for-byte.
Qwen/Qwen3.6-35B-A3B 35B-A3B MoE Upstream pre-Heretic base model. transformers-native multimodal weights.
FoolDev/Thanatos-27B-HERETIC 27B dense Sibling repo, and now a genuinely different model: a dense Qwen 3.8 27B, abliterated from the ARA-based heretic-org/Qwen3.8-27B-heretic-ara. Same teacher (Fable 5), same tooling, newer Qwen generation, no experts. Pick Thanatos for a smaller resident footprint and a dense compute profile; pick Janus for 35B-class capacity at ~3B active. (The older FoolDev/Thanatos-27B and Thanatos-27B-Heretic slugs now 307 to this path.)
Crownelius/Crow-9B-HERETIC-4.6 9B dense Heretic-flavored fine-tune on a smaller 9B Qwen base. Useful as a fast first-pass model when 35B is too heavy for the host.

Janus vs Thanatos. Since 0.7.0 the two are genuinely different models, not two abliterations of one base. Janus is Qwen 3.6 35B-A3B: a mixture of experts, ~34.7B parameters total with ~3B active per token, 40 layers, 256 experts (8 routed + 1 shared), on llmfan46's Heretic base, and its bundled quant is MTP-clean so no strip is needed. Thanatos is a dense Qwen 3.8 27B — every parameter on every token, 64 layers — on heretic-org's ARA base, and its bundle is MTP-stripped, because that base ships the NextN block. They still share the 262,144 native window, the ChatML frame, the Claude Fable 5 teacher slot and this repo's tooling. Choose on shape, not only on abliteration: Janus for 35B-class capacity at ~3B active and a KV cache under a third the size (0.625 vs 2 GiB per 32K at f16), Thanatos for the smaller resident footprint (16.1 vs 19.78 GiB of weights) and a newer Qwen generation.

Credits

License inherited from upstream: Apache-2.0.

Identity and Version

Repository
FoolDev/Janus-35B-HERETIC
Publisher
Fool
Task
Text generation
Modality
Text
Library
gguf
Parameters
Not stated by the source
Languages
en, zh, ru, es, fr, it, ja, ko
Revision
be7f5279e318d4a312abd7824e18ad89d48c58bd
First published
2026-05-20
Last updated
2026-09-18

Files and Weights

34 files, 21.2 GB in total. The weights are 1 file totalling 21.2 GB in gguf.

Weights1 file · 21.2 GB
Configuration8 files · 51.8 KB
Documentation4 files · 193.9 KB
Other19 files · 134.8 KB
Repository2 files · 2.3 KB
Every file
FileTypeSizeSHA-256
Janus-35B-A3B.Q4_K_M.ggufWeights21.2 GB b82f9f2155eb
examples/llama_cpp_quickstart.pyConfiguration2.9 KB
examples/llama_cpp_vision.pyConfiguration5.1 KB
examples/ollama_chat.pyConfiguration6.5 KB
examples/transformers_quickstart.pyConfiguration4.5 KB
scripts/check_bridge_sync.pyConfiguration8.2 KB
scripts/check_go_template.pyConfiguration9.5 KB
scripts/strip_mtp.pyConfiguration8.2 KB
scripts/verify_arch.pyConfiguration6.9 KB
CHANGELOG.mdDocumentation119.9 KB
LICENSEDocumentation11.3 KB
README.mdDocumentation58.5 KB
examples/README.mdDocumentation4.2 KB
CITATION.cffOther2.2 KB
MakefileOther3.2 KB
ModelfileOther11.2 KB
banner.pngOther9.7 KB
banner.svgOther5.1 KB
bmc-banner.svgOther5.4 KB
moe-routing.svgOther44.1 KB
paramsOther178 B
scripts/bench.shOther3.8 KB
scripts/build.shOther5.4 KB
scripts/cap_ctx.shOther2.9 KB
scripts/check.shOther10.3 KB
scripts/fetch_vision.shOther2.9 KB
scripts/install-hooks.shOther677 B
scripts/live_check.shOther13.0 KB
scripts/load_bundle.shOther5.0 KB
scripts/smoke_test.shOther7.0 KB
systemOther673 B
templateOther2.1 KB
.gitattributesRepository1.6 KB
.gitignoreRepository722 B

License and Download

License
apache-2.0
Access
Open weights, no gate
Download size
21.2 GB
Download from Fool

Released by Fool through its official repository on Hugging Face. Read the license.

Built From

  • Derived from llmfan46/Qwen3.6-35B-A3B-uncensored-heretic
  • Quantized from llmfan46/Qwen3.6-35B-A3B-uncensored-heretic
  • Trained on (disclosed) Crownelius/Creative_Writing_ShareGPT_Enhanced
  • Trained on (disclosed) Crownelius/Crow-Heretic-TeichAI-Unified
  • Trained on (disclosed) Crownelius/Opus-4.7-Reasoning
  • Trained on (disclosed) microsoft/rStar-Coder
  • Trained on (disclosed) openbmb/UltraData-Math
  • Trained on (disclosed) peteromallet/dataclaw-peteromallet

Memory Requirements

PrecisionWeights in memory
As published21.2 GB

Weights only, from the published parameter count; the key-value cache and runtime add to this.

Questions About Janus-35B-HERETIC

Can I use Janus-35B-HERETIC commercially?

Yes. Janus-35B-HERETIC is released under Apache License 2.0. The Apache License 2.0 is a permissive open-source license. It permits commercial use, modification and redistribution. It requires keeping the license and copyright notices and any NOTICE file, stating significant changes, and it includes an express patent grant from contributors.

Similar Models

Fine-tune Qwen3 (14B) for free using our Google Colab notebook! - Read our Blog about Qwen3 support: unsloth.ai/blog/qwen3 - View the rest of our notebooks in our docs here. Qwen3-Coder is available in multiple sizes. Today, we're excited to introduce Qwen3-Coder-30B-A3B-Instruct. This streamlined model maintains impressive performance and efficiency, featuring the following key enhancements: - Significant Performance among open models on Agentic Coding, Agentic Browser-Use, and other foundational coding tasks. - Long-context Capabilities with native support for 256K tokens, extendable up to 1M tokens using Yarn, optimized for repository-scale understanding. - Agentic Coding supporting for…

Open weights apache-2.0 transformers

Model · Text generation

opt-125m

AI at Meta

OPT was first introduced in Open Pre-trained Transformer Language Models and first released in metaseq's repository on May 3rd 2022 by Meta AI. Disclaimer: The team releasing OPT wrote an official model card, which is available in Appendix D of the paper. Content from this model card has been written by the Hugging Face team. To quote the first two paragraphs of the official paper OPT was predominantly pretrained with English text, but a small amount of non-English data is still present within the training corpus via CommonCrawl. The model was pretrained using a causal language modeling (CLM) objective. OPT belongs to the same family of decoder-only models like GPT-3. As such, it was…

Open weights other 2,048 tokens transformers

Model · Text generation

Ornith-1.5-9B-GGUF

Ornith

Chirp Chirp! We are introducing Ornith-1.5, a major step toward building foundation models through end-to-end self-improvement. Ornith-1.5 extends Ornith-1.0 (which was developed on top of Qwen3.5 and Gemma4 with additional continued pretraining, mid-training, and post-training) by expanding the self-improvement loop from scaffold and rollout optimization to jointly optimizing task generation, scaffold construction, and solution rollouts. Rather than relying on a fixed set of human-curated tasks and manually designed harnesses, Ornith-1.5 continuously generates new training tasks, discovers effective strategies for solving them, and improves the policy through reinforcement learning. For…

Open weights mit transformers

Model · Text generation

Ornith-1.5-35B-A3B-GGUF

Ornith

Chirp Chirp! We are introducing Ornith-1.5, a major step toward building foundation models through end-to-end self-improvement. Ornith-1.5 extends Ornith-1.0 (which was developed on top of Qwen3.5 and Gemma4 with additional continued pretraining, mid-training, and post-training) by expanding the self-improvement loop from scaffold and rollout optimization to jointly optimizing task generation, scaffold construction, and solution rollouts. Rather than relying on a fixed set of human-curated tasks and manually designed harnesses, Ornith-1.5 continuously generates new training tasks, discovers effective strategies for solving them, and improves the policy through reinforcement learning. For…

Open weights mit transformers

Model · Text generation

Ornith-1.0-9B-GGUF

Ornith

Aloha! Today, we are releasing Ornith-1.0, a self-improving family of open-source models for agentic coding. This model card documents Ornith-1.0-9B, the most lightweight member of the Ornith family, designed for efficient single-GPU deployment. Ornith-1.0-9B is a dense ~9B model (≈19 GB in bf16), so it serves comfortably on a single 80GB GPU. The recipes below stand up an OpenAI-compatible server; add --tensor-parallel-size / --tp if you want to shard across more GPUs. For a quick local test (or to script offline generation), load the model directly with Transformers. Make sure you have a recent release installed — see the Transformers installation guide; Ornith-1.0-9B requires…

Open weights mit transformers

Uncensored Qwen3.8-27B, published as GGUF quantizations with the multi token prediction (MTP) head retained and verified. Refusal behaviour has been substantially reduced, not eliminated. See Measured behaviour for the numbers. Capabilities, training data, and architecture are otherwise unchanged. - Refusal directions removed with Heretic, which co minimizes refusal count against KL divergence from the base model. No handwritten refusal removal code, no finetuning, no additional training data. - Abliteration runs at bf16 (no 4 bit quantization). the resulting LoRA is merged into the bf16 base, so the published weights are not a quantized round trip. - mtp. tensors are copied verbatim from…

Open weights apache-2.0 llama.cpp