Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions atlas/cli/commands/model_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,13 @@ def _unsloth_qwen35_url(repo: str, file: str) -> str:
f"{_UNSLOTH_QWEN35_COMMIT}/{file}")


_UNSLOTH_QWEN36_COMMIT = "5cb35eb3dcbf52dbce5f87dbc64df6aaffadcace"

def _unsloth_qwen36_url(file: str) -> str:
return (f"https://huggingface.co/unsloth/Qwen3.6-27B-MTP-GGUF/resolve/"
f"{_UNSLOTH_QWEN36_COMMIT}/{file}")


# Single source of truth. Order: by tier (cpu → xlarge), then by quant.
#
# Truthful state today:
Expand Down Expand Up @@ -333,6 +340,34 @@ def _unsloth_qwen35_url(repo: str, file: str) -> str:
"llama.cpp model only — G(x) verification will silently "
"no-op (--no-lens to acknowledge). See PC-058 roadmap.",
),
Model(
name="Qwen3.6-27B-MTP-UD-Q4_K_XL",
tier="xlarge",
model_file="Qwen3.6-27B-UD-Q4_K_XL.gguf",
model_display="Qwen3.6 27B MTP (UD-Q4_K_XL)",
model_size_gb=16.7,
lens_status="no-artifacts",
download_url=_unsloth_qwen36_url("Qwen3.6-27B-UD-Q4_K_XL.gguf"),
sha256="4085665ee36d82a672a238a43f0e5643f2f0e39f2d7bd5d373f0ef10ecf53095",
license="Apache-2.0",
requires_hf_token=False,
asa_status="supported",
asa_artifact_files=["ast_edit_steering.gguf"],
asa_hf_repo="yogthos/atlas-asa-qwen3.6-27b-mtp-ud-q4_k_xl",
notes="Qwen3.6-27B with Multi-Token Prediction. Gated DeltaNet + "
"Gated Attention hybrid architecture, 5120-dim hidden. "
"MTP supported in llama.cpp since PR #22673. Requires "
"--spec-type draft-mtp --spec-draft-n-max 2 flags. "
"ASA control vector (ast_edit_steering.gguf, layer 27, "
"5120-dim) published at "
"https://huggingface.co/yogthos/atlas-asa-qwen3.6-27b-mtp-ud-q4_k_xl. "
"Lens C(x) cost_field.pt trained locally (5120-dim, "
"200-epoch contrastive) but not yet published on HF, and "
"the G(x) classifier half (gx_*.json) is untrained — G(x) "
"will silently no-op until both lens halves ship via "
"`atlas lens publish`. macOS Metal: MTP disabled by default "
"(ATLAS_ENABLE_MTP=0); see llama.cpp #23011/#23752.",
),
Model(
name="gemma-4-12b-it-Q4_K_M",
tier="medium",
Expand Down
127 changes: 127 additions & 0 deletions docs/models/qwen3.6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
# Qwen3.6-27B-MTP on ATLAS (macOS Metal)

## Model specs

- Architecture: Gated DeltaNet + Gated Attention hybrid, 5120-dim hidden, 64 layers
- MTP: Multi-Token Prediction (inline draft head, `--spec-type draft-mtp`)
- Context: 262K native, 32K recommended for 64GB M1 Max
- Quantization: UD-Q4_K_XL (19 GB on disk, ~24 GB VRAM at 32K context)
- License: Apache 2.0

## What works

- Base inference via Metal-accelerated llama.cpp
- Lens C(x) cost-field scoring (5120-dim, 200-epoch contrastive training)
- Full V3 pipeline (budget forcing, plan search, candidate selection, refinement loop)

## What doesn't

- **MTP speculative decoding**: crashes during draft context init (`GGML_ASSERT missing result_norm/result_embd`) and has net throughput loss on Metal even when it doesn't crash (llama.cpp #23752). Disabled by default (`ATLAS_ENABLE_MTP=0`).
- **ASA steering vectors**: no vector trained for Qwen3.6 residuals. Would need `atlas asa build` against this model.
- **e2e_smoke in atlas doctor**: 300 tokens × ~5 tok/s on M1 Max exceeds the 60s hard timeout. The model itself works fine for interactive use.

## Fresh clone setup

```bash
# 1. Clone and configure
git clone https://github.com/itigges22/ATLAS
cd ATLAS
cp .env.example .env

# Edit .env:
# ATLAS_MODEL_FILE=Qwen3.6-27B-UD-Q4_K_XL.gguf
# ATLAS_MODEL_NAME=Qwen3.6-27B-MTP-UD-Q4_K_XL
# ATLAS_ENABLE_MTP=0

# 2. Download the model (17.9 GB)
hf download unsloth/Qwen3.6-27B-MTP-GGUF \
--include "*UD-Q4_K_XL*" \
--local-dir ./models

# 3. Build native Metal llama-server
./scripts/atlas-setup-macos.sh

# 4. Start the native server (keep this terminal open)
source .env
./scripts/atlas-llama-macos.sh

# 5. Start Docker services (new terminal)
docker compose -f docker-compose.yml -f docker-compose.macos.yml up -d

# 6. Verify
export ATLAS_MODEL_FILE=Qwen3.6-27B-UD-Q4_K_XL.gguf
atlas doctor
```

## Lens training (optional, ~2h on CPU)

```bash
# Download pre-computed 5120-dim embeddings
curl -sL "https://huggingface.co/datasets/itigges22/ATLAS/resolve/main/embeddings/training_embeddings_5120d.json" \
-o ./geometric-lens/geometric_lens/models/qwen36-27b/training_embeddings_5120d.json

# Copy data into the running geometric-lens container
docker cp ./geometric-lens/geometric_lens/models/qwen36-27b/training_embeddings_5120d.json \
atlas-geometric-lens-1:/tmp/

# Train C(x) inside the container (torch is pre-installed there)
docker exec -w /app atlas-geometric-lens-1 python3 -c "
import json, os
from geometric_lens.training import train_cost_field, save_cost_field

with open('/tmp/training_embeddings_5120d.json') as f:
data = json.load(f)
data['labels'] = [1 if l == 'PASS' else 0 for l in data['labels']]
print(f'Loaded {len(data[\"embeddings\"])} embeddings, dim={data[\"dim\"]}')

result = train_cost_field(data, epochs=200)
test_auc = result.get('best_test_auc') or result.get('final_test_auc') or 0.0
print(f'Test AUC: {test_auc:.4f}')

os.makedirs('/tmp/qwen36-27b', exist_ok=True)
cost_path = save_cost_field(result['model'], save_dir='/tmp/qwen36-27b')
print(f'Saved: {cost_path}')
"

# Copy trained artifact back to host
docker cp atlas-geometric-lens-1:/tmp/qwen36-27b/cost_field.pt \
./geometric-lens/geometric_lens/models/qwen36-27b/

# Doctor requires metric_tensor.pt on disk (runtime uses XGBoost, not this file)
touch ./geometric-lens/geometric_lens/models/qwen36-27b/metric_tensor.pt

# Verify Lens
export ATLAS_LENS_MODELS=./geometric-lens/geometric_lens/models/qwen36-27b
atlas doctor
```

## Expected doctor output

```
✓ health/llama ok
✓ model_file Qwen3.6-27B-UD-Q4_K_XL.gguf (16.7 GB)
✓ lens_weights cost_field.pt + metric_tensor.pt (after training)
⚠ asa_steering expected — no vector trained for Qwen3.6
⚠ tier_constraints disk free — Qwen3.6 is 17.9 GB
✗ e2e_smoke timeout — 27B on M1 Max is slow, not a bug

19 passed, 2 warnings, 1 failed, 1 skipped
ATLAS install has failures — re-run with -v for detail.
```

## Registry entry

The model is registered in `atlas/cli/commands/model_registry.py` as:

- `name`: `Qwen3.6-27B-MTP-UD-Q4_K_XL`
- `tier`: `xlarge`
- `lens_status`: `no-artifacts` (until artifacts are published to HF)
- `download_url`: `None` (manual download via `hf download`)

## Key files

- `atlas/cli/commands/model_registry.py` — registry entry
- `inference/Dockerfile.v31` — llama.cpp SHA `25558268` (MTP merge)
- `inference/patches/expose-hidden-states.patch` — regenerated for new upstream
- `scripts/atlas-llama-macos.sh` — MTP flag gating via `ATLAS_ENABLE_MTP`
- `geometric-lens/geometric_lens/models/qwen36-27b/` — Lens artifacts
Binary file not shown.
30 changes: 30 additions & 0 deletions geometric-lens/geometric_lens/models/qwen36-27b/train_cx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env python3
"""Train C(x) cost field from pre-computed 5120-dim embeddings."""
import json, os, sys, time

path = "/app/geometric_lens/models/qwen36-27b/training_embeddings_5120d.json"
with open(path) as f:
data = json.load(f)

sys.stderr.write(f"Loaded {len(data['embeddings'])} embeddings, dim={data['dim']}\n")
labels = [1 if l == "PASS" else 0 for l in data["labels"]]
data["labels"] = labels
sys.stderr.write(f"Labels: {sum(labels)} PASS, {len(labels) - sum(labels)} FAIL\n")
sys.stderr.flush()

from geometric_lens.training import train_cost_field, save_cost_field

start = time.time()
result = train_cost_field(data, epochs=200, lr=1e-3, margin=1.0)
elapsed = time.time() - start

test_auc = result.get("best_test_auc") or result.get("final_test_auc") or 0.0
train_auc = result.get("final_train_auc") or 0.0
sys.stderr.write(f"Train AUC: {train_auc:.4f} | Test AUC: {test_auc:.4f} | Time: {elapsed:.0f}s\n")
sys.stderr.flush()

artifact_dir = "/app/geometric_lens/models/qwen36-27b"
cost_path = save_cost_field(result["model"], save_dir=artifact_dir)
sys.stderr.write(f"Saved: {cost_path}\n")
sys.stderr.flush()
print("DONE")
2 changes: 1 addition & 1 deletion inference/Dockerfile.v31
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ COPY patches/ /patches/
# 1. There's a llama.cpp release with a feature/fix we want
# 2. The PC-202 patch has been regenerated against the new upstream
# Override at build time: --build-arg LLAMA_CPP_REV=<sha>
ARG LLAMA_CPP_REV=2e97c5f96f9fe2bb26f794a348e05d7a1c74baa1
ARG LLAMA_CPP_REV=255582687b8dd211fdbc582e43ab842491554e94
# #117: Split fetch -> patch -> build into three RUN layers so a
# LLAMA_CPP_REV bump or a patches/ change invalidates only the affected
# layer + everything below, not the whole giant step. The build is the
Expand Down
Loading