A self-built, end-to-end local AI reasoning pipeline -- an independent AI system with its own Mixture-of-Experts architecture.
Focused on structured reasoning, bilingual behavior steering,
adapter-based fine-tuning, and honest compliance boundaries. Tokenizer: SnapSurf Minor Tokenizer 2.1 (SSMT)
SnapSurf Minor 2.1 is a separately built local AI project focused on structured reasoning, behavior steering, and adapter-based training around a custom open-weight runtime stack. It is designed as its own build, with a dedicated CLI, behavior bundle system, SFT/LoRA pipeline, safetensors inspection tooling, and verification flow instead of acting like a thin wrapper around a generic chat app.
SnapSurf Minor 2.1 includes:
Component
Description
Runtime Steering
Controls model behavior through behavior bundles (system prompt + profile) without modifying weights
SFT Seed Data
Bilingual Vietnamese/English training dataset in "harmony" format for supervised fine-tuning
Skill Compliance Data
Dedicated dataset enforcing honest boundaries between runtime-only, training-ready, and learned behavior
LoRA/QLoRA Training
Complete adapter training pipeline with fixed train/eval splits, early stopping, gradient checkpointing
Multi-turn Chat
Interactive terminal chat with conversation history and dynamic reasoning effort switching
Heuristic Evaluation
Scores outputs against a trait checklist and rubric rules, including skill compliance traits
Safetensors Inspector
Header-only audit of the local weight file, validating tensor shapes against architecture config
Artifact Reporter
Hashes base weights, adapter outputs, eval files, and classifies the strongest supportable claim level
Unified CLI
Single entry point for all 56 Python scripts via snapsurf_minor_cli.py (50 commands)
Key Features
Bilingual (Vietnamese/English) -- defaults to Vietnamese when the user writes in Vietnamese
Behavior Bundles -- cleanly separates system prompt, profile, SFT data, skill compliance data, and eval cases
3 Reasoning Levels -- low, medium, high -- switchable mid-session
1flowchart TD
2 A["User Input"]--> B["Load Behavior Bundle<br/>(system_prompt.txt)"]3 B --> C["Build messages array<br/>[system, user]"]4 C --> D["tokenizer.apply_chat_template()<br/>with reasoning_effort"]5 D --> E["model.generate()<br/>max_new_tokens, temperature, top_p"]6 E --> F["Decode completion tokens"]7 F --> G["extract_analysis_text()<br/>Parse channel=analysis<br/>Truncate to 700 chars max<br/>Strip internal markers<br/>(hidden by default)"]8 F --> H["extract_final_text()<br/>Parse channel=final<br/>Clean channel tokens<br/>Normalize whitespace<br/>(shown to user)"]9 G --> I["Return JSON response<br/>{ final_text, analysis_text, decoded_completion }"]10 H --> I
Training Flow
mermaid
1flowchart TD
2 A["harmony_sft_vi.jsonl<br/>(49 base examples)"]--> C
3 B["harmony_sft_skill_compliance_vi.jsonl<br/>(48+ skill compliance examples)"]--> C
4 C["prepare_deepthinkingflow_training_assets.py<br/>Validate all rows<br/>Split skill compliance by category<br/>Merge base + skill compliance<br/>Ensure train/eval disjoint"]5 C --> D["combined.train.jsonl"]6 C --> E["combined.eval.jsonl"]7 D & E --> F["train_transformers_deepthinkingflow_lora.py<br/>Load config.example.json or config.qlora.example.json"]8 F --> PF["Preflight Checks<br/>Validate config + dataset paths<br/>Verify bundle health<br/>Tokenizer precheck"]9 PF --> G["Load base model<br/>bf16 or 4-bit NF4 (QLoRA)"]10 G --> H["Apply LoraConfig<br/>r=24, alpha=48, dropout=0.03<br/>target: q_proj, k_proj, v_proj, o_proj"]11 H --> TV{"Target Module Validation"}12 TV --All 8 targets hit--> I["Confirm trainable_params > 0<br/>trainable_params=39936<br/>trainable_ratio=0.00076222"]13 TV --Missing targets--> FAIL1["FAIL: missing module hit"]14 I --> J["HuggingFace Trainer<br/>Cosine LR scheduler<br/>Gradient checkpointing<br/>EarlyStopping (patience=3)"]15 J --> K["Save adapter to out/"]16 K --> AR["Artifact Report<br/>SHA-256 hash base weights<br/>Hash adapter outputs<br/>Classify claim level"]17 AR --> L{"merge_after_train?"}18 L --Yes--> M["PeftModel.merge_and_unload()<br/>Save merged to out/*-merged/"]19 L --No--> N["Done"]20 M --> N
The original/model.safetensors file is approximately 12.82 GiB and contains 363 tensors total: 3 global tensors and 15 tensors repeated across each of the 24 transformer blocks. This section documents every tensor, its dtype, and its shape based on the safetensors header and the companion dtypes.json metadata.
Global Tensors (3 total)
Tensor Name
Logical Dtype
Shape
Purpose
embedding.weight
BF16
[201088, 2880]
Token embedding matrix
norm.scale
BF16
[2880]
Final RMS normalization scale
unembedding.weight
BF16
[201088, 2880]
Output projection (LM head)
Per-Block Tensors (15 per block, 24 blocks, 360 total)
Each block.N (where N = 0..23) contains the following tensors:
Attention Sub-block (6 tensors):
Tensor Pattern
Logical Dtype
Shape
Purpose
block.N.attn.norm.scale
BF16
[2880]
Pre-attention RMS normalization
block.N.attn.qkv.weight
BF16
[5120, 2880]
Fused Q/K/V projection weight
block.N.attn.qkv.bias
BF16
[5120]
Fused Q/K/V projection bias
block.N.attn.sinks
BF16
[64]
Attention sink values (one per query head)
block.N.attn.out.weight
BF16
[2880, 4096]
Attention output projection weight
block.N.attn.out.bias
BF16
[2880]
Attention output projection bias
The fused QKV dimension of 5120 is derived from: (64 query heads * 64 head_dim) + (2 * 8 KV heads * 64 head_dim) = 4096 + 1024 = 5120. The attention output width of 4096 is: 64 query heads * 64 head_dim.
MLP / MoE Sub-block (9 tensors):
Tensor Pattern
Logical Dtype
Shape
Purpose
block.N.mlp.norm.scale
BF16
[2880]
Pre-MLP RMS normalization
block.N.mlp.gate.weight
BF16
[32, 2880]
MoE router gate weight (32 experts)
block.N.mlp.gate.bias
BF16
[32]
MoE router gate bias
block.N.mlp.mlp1_weight.blocks
FP4
[32, 5760, ...]
SwiGLU up-projection packed FP4 blocks
block.N.mlp.mlp1_weight.scales
UE8
[32, 5760, ...]
SwiGLU up-projection quantization scales
block.N.mlp.mlp1_bias
BF16
[32, 5760]
SwiGLU up-projection bias
block.N.mlp.mlp2_weight.blocks
FP4
[32, 2880, ...]
SwiGLU down-projection packed FP4 blocks
block.N.mlp.mlp2_weight.scales
UE8
[32, 2880, ...]
SwiGLU down-projection quantization scales
block.N.mlp.mlp2_bias
BF16
[32, 2880]
SwiGLU down-projection bias
The MLP dimension of 5760 is: 2 * intermediate_size (2880) for the SwiGLU gated architecture. FP4 tensors use packed 4-bit representation with UE8 per-channel quantization scales. Each expert is stored as a separate slice along dimension 0 (32 experts total, 4 active per token).
Packed 4-bit MoE expert weights (mlp1 and mlp2 blocks)
UE8
48
Unsigned 8-bit quantization scales for FP4 expert weights
Total
363
What is Inside vs Outside the Weights
Inside model.safetensors
Outside model.safetensors
Embedding, attention, MoE, LM head tensors
behavior/SnapSurfMinor/system_prompt.txt
Block tensor names, shapes, and dtypes
skills/SnapSurfMinor/SKILL.md
Packed FP4 expert weights and BF16 biases
behavior/SnapSurfMinor/profile.json
Final norm and vocab matrices
All Python scripts in scripts/
Nothing else
All training datasets and eval cases
Nothing else
LoRA config and adapter artifacts
Nothing else
Chat template and tokenizer JSON
Prerequisites
System Requirements
Item
Minimum
Recommended
Python
3.10+
3.11+
RAM
16 GiB
32 GiB+
GPU VRAM
16 GiB (QLoRA 4-bit)
24 GiB+ (LoRA bf16)
Disk
15 GiB (weights)
30 GiB (weights + outputs)
Install Dependencies
For inference (running the model):
pip install -r requirements-transformers.txt
For training (LoRA/QLoRA fine-tuning):
bash
1python scripts/snapsurf_minor_cli.py bootstrap-training-env
23# If using QLoRA (4-bit quantization):4pip install"bitsandbytes>=0.49.2,<1.0.0"
Dependency details
Inference:
Package
Version
transformers
>=5.5.4, <6.0.0
tokenizers
>=0.22.2, <1.0.0
huggingface_hub
>=1.11.0, <2.0.0
safetensors
>=0.7.0, <1.0.0
jinja2
>=3.1.6, <4.0.0
Training (additional):
Package
Version
torch
>=2.11.0, <3.0.0
accelerate
>=1.13.0, <2.0.0
datasets
>=4.8.4, <5.0.0
peft
>=0.19.1, <1.0.0
Quick Start
1. Bootstrap the model directory from HuggingFace
bash
1# Download metadata (tokenizer, config, chat template) -- does NOT include weights2python scripts/snapsurf_minor_cli.py bootstrap
34# Or include weights (~12.8 GiB):5python scripts/snapsurf_minor_cli.py bootstrap --include-weights
2. (Optional) Link local weights
If you already have model.safetensors in the original/ directory:
It does not convert model.safetensors into an Ollama-native model by itself.
Ollama still needs a valid base model tag such as llama3.1:8b, qwen2.5:7b, or another model already supported by your Ollama install.
If you want to run SnapSurf Minor 2.1 weights directly in Ollama, you still need a separate conversion path to an Ollama-compatible format.
Production Notes
export-runtime is a bridge layer, not a training or merge step.
train_transformers_deepthinkingflow_lora.py now hard-fails on duplicate target modules, invalid numeric knobs, missing resume checkpoints, and overlapping train/eval rows.
External host compatibility is now explicit rather than implied: runtime-only claims stay outside weight-level claims.
preflight-all gives one consolidated JSON snapshot over bundle health, runtime soft gates, training feasibility, dependency presence, and external-host readiness.
verify is the shortest release-style local check because it combines bundle validation, project preflight, and the smoke suite.
release-manifest turns verify/artifact state into a release-oriented JSON manifest.
.github/workflows/verify.yml runs the core verification path automatically on push and pull request.
4. Interactive chat
python scripts/snapsurf_minor_cli.py chat
5. One-shot generation
python scripts/snapsurf_minor_cli.py run --user "Explain MoE architecture"
All scripts are accessed through the unified CLI launcher. The table below lists the main command groups plus the newer accelerator and Apple/MLX verification commands.
Interactive multi-turn chat with conversation history
run
run_transformers_deepthinkingflow.py
One-shot generation returning JSON
inspect-weights
inspect_safetensors_model.py
Audit safetensors file without loading tensors into RAM
render-prompt
render_transformers_deepthinkingflow_prompt.py
Render the injected chat-template prompt
compose-request
compose_behavior_request.py
Compose messages from the behavior bundle
validate-bundle
validate_behavior_bundle.py
Validate bundle health including skill compliance
bootstrap
bootstrap_transformers_deepthinkingflow.py
Bootstrap model directory from HF
bootstrap-training-env
bootstrap_training_env.py
Install training deps into .venv-tools
assemble-model-dir
assemble_local_transformers_model_dir.py
Symlink local weights into model dir
prepare-sft
prepare_harmony_sft_dataset.py
Deduplicate + split base SFT dataset
prepare-training-assets
prepare_deepthinkingflow_training_assets.py
Build combined train/eval with skill compliance splits
generate-skill-compliance
generate_skill_compliance_corpus.py
Regenerate expanded skill-compliance dataset and eval corpus
train-lora
train_transformers_deepthinkingflow_lora.py
Train LoRA/QLoRA adapter with dry-run support
preflight-all
preflight_deepthinkingflow_project.py
Consolidated preflight across bundle, runtime, training, and external hosts
verify
verify_deepthinkingflow_project.py
Consolidated verification across bundle validation, preflight, and smoke tests
release-manifest
build_release_manifest.py
Release-oriented manifest combining verify and artifact state
eval
evaluate_reasoning_outputs.py
Score outputs against trait + rubric checklist
report-artifacts
report_deepthinkingflow_artifacts.py
Hash artifacts and classify claim level
doctor
doctor_deepthinkingflow.py
Release-style health report across verify, claim gates, readiness, and artifacts
preflight-train
preflight_deepthinkingflow_training.py
Estimate whether a training config is feasible on the current machine
prepare-datasets
prepare_external_datasets.py
Prepare external reasoning/coding datasets into chat-formatted assets
build-external-train-bundle
build_external_training_bundle.py
Build train/eval JSONL bundles from prepared external datasets
benchmark-runtime
benchmark_deepthinkingflow_runtime.py
Measure prompt rendering and tokenizer throughput
cuda-backend-status
cuda_backend_status.py
Report CUDA backend scaffold/build readiness
apple-backend-status
apple_backend_status.py
Report Apple backend scaffold/build readiness
apple-mlx-status
apple_mlx_adapter_status.py
Report MLX adapter readiness and Apple-path contract
apple-mlx-inference-status
apple_mlx_inference_scaffold_status.py
Report tokenizer, generation, and claim-boundary status for Apple path
apple-mlx-generation-contract
apple_mlx_generation_contract_check.py
Verify prompt packaging and sampling contract for Apple path
apple-mlx-kv-decode
apple_mlx_kv_decode_contract_check.py
Verify KV-cache decode expectations for sliding/full layers
apple-mlx-e2e-verify
apple_mlx_end_to_end_verify.py
Run Apple-path end-to-end contract verification without claiming native execution
accelerator-readiness
accelerator_readiness_report.py
Unified readiness view for optional CUDA and Apple backends
accelerator-doctor
accelerator_doctor.py
Native acceleration doctor report with claim ceiling and missing capability list
backend-build
backend_build_helper.py
[NEW] Build Apple Silicon and/or CUDA backends with auto-detection
backend-status
deepthinkingflow_backends.py
[NEW] Display status and capabilities of all available backends
backend-benchmark
backend_benchmark.py
[NEW] Benchmark inference speed across backends for performance comparison
backend-diagnostics
backend_diagnostics.py
[NEW] Run comprehensive system diagnostics for backend readiness
release-build
create_release_package.py
[NEW - Phase 5] Create production release packages with checksums
multi-gpu-status
backend_multi_gpu.py
[NEW - Phase 6] Display multi-GPU status and allocation recommendations
quantization-status
backend_quantization.py
[NEW - Phase 6] Check quantization backends and estimate model compression
backend-fallback
backend_fallback.py
[NEW - Phase 6] Manage backend failures and recovery strategies
Chat Commands (inside a chat session)
/help Show available commands
/status Show current runtime settings
/clear Clear history, keep system prompt
/history Print the retained conversation
/analysis on|off Toggle visible analysis output
/reasoning <level> Switch reasoning effort: low, medium, high
/quit Exit the chat session
Workflows
1. Inference Workflow
Use an existing model to generate answers.
mermaid
1flowchart TD
2 A["Obtain model weights<br/>(bootstrap --include-weights<br/>OR place in original/)"]
3 A --> B["Assemble model directory<br/>(assemble-model-dir)"]4 B --> C["Validate behavior bundle<br/>(validate-bundle behavior/SnapSurfMinor)"]5 C --> D{"Choose mode?"}6 D -- One-shot --> E["run --user 'prompt'<br/>--reasoning-effort high<br/>--include-analysis"]
7 E --> F["JSON output<br/>{ final_text, analysis_text }"]8 D -- Multi-turn chat --> G["chat<br/>--reasoning-effort high<br/>--show-analysis<br/>--max-history-turns 6"]
9 G --> H["Interactive session<br/>SnapSurfMinor 2.1> ..."]
analysis -- Visible reasoning (hidden by default; enable via --show-analysis or /analysis on)
final -- The final answer shown to the user
Generation Config
Parameter
Value
bos_token_id
199998
eos_token_id
[200002, 199999, 200012]
pad_token_id
199999
do_sample
true
Training Configuration
LoRA Config (Final Trained Values)
Parameter
Value
Description
lora_r
24
Rank of LoRA matrices (evolved from 4 through 4 milestones)
lora_alpha
48
Scaling factor (evolved from 8)
lora_dropout
0.03
Dropout rate (reduced from 0.05)
target_modules
[q_proj, k_proj, v_proj, o_proj]
Attention projection layers
bf16
true
BFloat16 precision
learning_rate
0.0002
Peak learning rate
lr_scheduler_type
cosine
Cosine decay scheduler
gradient_checkpointing
true
Saves VRAM
gradient_accumulation_steps
8
Effective batch = 1 x 8 = 8
max_seq_length
4,096
Maximum sequence length
early_stopping_patience
3
Stop if eval_loss does not improve for 3 consecutive evals
optim
adamw_torch
Optimizer
attn_implementation
eager
Attention backend
dataset_path
Combined train split
Base + skill compliance examples
eval_dataset_path
Combined eval split
Base + skill compliance eval
QLoRA Config (config.qlora.example.json)
Same as LoRA, with these additions:
Parameter
Value
Description
use_qlora
true
Enables QLoRA mode
load_in_4bit
true
Loads model in 4-bit (NF4)
optim
paged_adamw_8bit
Memory-efficient optimizer
Note: QLoRA requires the bitsandbytes package.
Training Parameter Evolution
SnapSurf Minor 2.1 underwent 4 progressive iterations of adapter parameter scaling, increasing trainable parameters from baseline to 6x the original count. All iterations completed successfully with passing training runs, artifact report verification, and the current full smoke suite (114/114).
Evolution Summary
Milestone
lora_r
lora_alpha
lora_dropout
Epochs
Learning Rate
Train Samples
Eval Samples
Trainable Params
Train Loss
Eval Loss
Baseline
4
8
0.05
1
0.0005
8
4
6,656
12.2351
12.2371
Reform 1
8
16
0.05
2
0.00035
12
6
13,312
12.2199
12.2248
Reform 2
16
32
0.05
3
0.00025
16
8
26,624
12.1929
12.1814
Reform 3 (Final)
24
48
0.03
3
0.00025
16
8
39,936
12.1677
12.1403
Parameter Growth Trajectory
Milestone
Trainable Params
Delta
Multiplier vs Baseline
Baseline
6,656
--
1x
Reform 1
13,312
+6,656
2x
Reform 2
26,624
+13,312
4x
Reform 3 (Final)
39,936
+13,312
6x
Total growth: 6,656 to 39,936 (+33,280 parameters, 6x baseline)
Modularity -- Each script does one thing; the CLI orchestrates everything.
Verifiability -- The safetensors inspector can audit the weight file header-only without loading tensors into RAM. The artifact reporter hashes and classifies claim levels.