Instructions to use Frankenstein-Labs/cortex.6.sol with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Frankenstein-Labs/cortex.6.sol with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="Frankenstein-Labs/cortex.6.sol")# pip install -U transformers accelerate # Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Frankenstein-Labs/cortex.6.sol") model = AutoModelForCausalLM.from_pretrained("Frankenstein-Labs/cortex.6.sol", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Frankenstein-Labs/cortex.6.sol with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Frankenstein-Labs/cortex.6.sol" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Frankenstein-Labs/cortex.6.sol", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/Frankenstein-Labs/cortex.6.sol
- SGLang
How to use Frankenstein-Labs/cortex.6.sol 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 "Frankenstein-Labs/cortex.6.sol" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Frankenstein-Labs/cortex.6.sol", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'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 "Frankenstein-Labs/cortex.6.sol" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Frankenstein-Labs/cortex.6.sol", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use Frankenstein-Labs/cortex.6.sol with Docker Model Runner:
docker model run hf.co/Frankenstein-Labs/cortex.6.sol
fix(vision): unpack processor output by keyword in native fusion
Browse filesTransformers image processors return BatchFeature (a UserDict, not a dict
subclass), so the isinstance(..., dict) check failed and the processor output
was passed positionally into the encoder's input_ids parameter. Against a real
encoder this raised ValueError: You have to specify input_ids.
Test against collections.abc.Mapping instead, and add a regression test using a
UserDict-based processor that fails on the previous code.
Also add AGENTS.md recording verified repo facts, sizing constraints, licensing
corrections and the small-model testing approach.
Co-authored-by: openhands <openhands@all-hands.dev>
- AGENTS.md +95 -0
- cortex_ai/vision/native.py +8 -1
- tests/test_native_fusion.py +28 -0
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# CORTEX AI — verified facts and constraints
|
| 2 |
+
|
| 3 |
+
This file records what was *measured* in this workspace, so later sessions do not re-derive it
|
| 4 |
+
or repeat claims that turn out to be wrong.
|
| 5 |
+
|
| 6 |
+
## Repository state
|
| 7 |
+
|
| 8 |
+
- `Frankenstein-Labs/Cortex-ai` HEAD = `a82e5d802d597d9429a4ecd1d4d0160e4f4eb4ad`
|
| 9 |
+
("feat(cortex-ai): add native vision fusion prototype"), branch `main`, no open PRs, no tags.
|
| 10 |
+
- The repo is a **redistribution** of `deepseek-ai/DeepSeek-V4-Pro-0813`.
|
| 11 |
+
- All 66 `model-*.safetensors` shards plus `model.safetensors.index.json` have SHA-256
|
| 12 |
+
**identical to upstream** (67/67 LFS objects match). Verified via the HF tree API.
|
| 13 |
+
- There is no `git-lfs` binary in this image. Fetch weights as pointer files only:
|
| 14 |
+
set `GIT_LFS_SKIP_SMUDGE=1` and neutralise the smudge filter, otherwise a clone pulls ~893 GB
|
| 15 |
+
into a 25 GB disk.
|
| 16 |
+
|
| 17 |
+
## Model facts (from `config.json`)
|
| 18 |
+
|
| 19 |
+
| Field | Value |
|
| 20 |
+
|---|---|
|
| 21 |
+
| architecture | `DeepseekV4ForCausalLM` (`model_type: deepseek_v4`) |
|
| 22 |
+
| hidden_size | 7168 |
|
| 23 |
+
| layers | 61 (+3 MTP) |
|
| 24 |
+
| vocab | 129280 |
|
| 25 |
+
| max positions | 1048576 |
|
| 26 |
+
| routed experts | 384, 6 per token |
|
| 27 |
+
| expert storage | `fp4`; weights FP8 `e4m3` |
|
| 28 |
+
| declared dtype | bfloat16 |
|
| 29 |
+
| tie_word_embeddings | false |
|
| 30 |
+
|
| 31 |
+
`tie_word_embeddings: false` means there is no `lm_head`-sharing trick for grafting new
|
| 32 |
+
modalities; any new vocabulary or modality embedding needs explicit, trained parameters.
|
| 33 |
+
|
| 34 |
+
## Sizing reality
|
| 35 |
+
|
| 36 |
+
- Stored payload ≈ 892.76 GB; ~1.65 T params. Minimum inference memory at 1 byte/param ≈ 1.65 TB.
|
| 37 |
+
- This development sandbox: **4 CPU cores, ~15 GiB RAM, 25 GB disk, no GPU** (`nvidia-smi`
|
| 38 |
+
absent, no `/dev/nvidia*`).
|
| 39 |
+
- Consequence: the 1.65 T checkpoint **cannot be loaded, run, or fine-tuned here**. Any plan
|
| 40 |
+
requiring an end-to-end forward pass of the real checkpoint is not executable in this
|
| 41 |
+
environment. Validate fusion paths against small stand-ins instead.
|
| 42 |
+
|
| 43 |
+
## Cost warning for "keep the weights untouched" plans
|
| 44 |
+
|
| 45 |
+
A vision projector must map into a 7168-dim space, but pretrained open projectors map to their
|
| 46 |
+
own models' hidden sizes (e.g. 4096). A randomly-initialised projector produces **noise** into the
|
| 47 |
+
core, so "never train anything" and "native vision that works" are mutually exclusive. Expected
|
| 48 |
+
behaviour must be stated honestly as an untrained prototype, or the projector must be trained.
|
| 49 |
+
Training a projector alone (frozen encoder + frozen core) is the cheap option; full multimodal
|
| 50 |
+
pretraining at 1.65 T is not affordable outside a cluster.
|
| 51 |
+
|
| 52 |
+
## Licensing corrections (checked against the Hub, not from memory)
|
| 53 |
+
|
| 54 |
+
Claims that appear in circulating roadmap documents are wrong in several places:
|
| 55 |
+
|
| 56 |
+
| Model | Claimed | Actual (verified) |
|
| 57 |
+
|---|---|---|
|
| 58 |
+
| Qwen2.5-VL | "non-commercial" | Apache-2.0 (7B and 72B both Apache) |
|
| 59 |
+
| LLaVA | "MIT" | `llama2` license (7B hub repo) |
|
| 60 |
+
| SDXL | "non-commercial RAIL" | OpenRAIL++-M — permits commercial use with use-restrictions |
|
| 61 |
+
| Coqui TTS | "MIT" | Coqui Public Model License — non-commercial |
|
| 62 |
+
| Kimi K2.5 | "Modified MIT, 5B + MoonViT" | Modified MIT, but **1.03 T params**, `image-text-to-text` |
|
| 63 |
+
| HunyuanVideo | "community, non-commercial" | Tencent Hunyuan Community; **explicitly does not apply in EU/UK/South Korea** |
|
| 64 |
+
| Wan2.2 | Apache-2.0 | confirmed Apache-2.0, claims no rights over outputs |
|
| 65 |
+
|
| 66 |
+
Note the Qwen 2.5 vs 3 split: `Qwen2.5-VL-*` is Apache, but Qwen3-VL and some Qwen3 text models
|
| 67 |
+
carry the `qwen` license. Check each repo individually; never generalise from a family name.
|
| 68 |
+
|
| 69 |
+
## Known bug found and fixed
|
| 70 |
+
|
| 71 |
+
`cortex_ai/vision/native.py::encode_image` branched on `isinstance(model_input, dict)`.
|
| 72 |
+
Transformers image processors return `BatchFeature`, which derives from `UserDict`, **not** from
|
| 73 |
+
`dict`. The check therefore failed and the processor output was passed positionally into
|
| 74 |
+
`SiglipModel.forward(input_ids=...)`, raising
|
| 75 |
+
`ValueError: You have to specify input_ids`.
|
| 76 |
+
|
| 77 |
+
Fixed by testing `isinstance(model_input, Mapping)`. Regression test:
|
| 78 |
+
`tests/test_native_fusion.py::test_processor_output_is_unpacked_by_keyword_not_positionally`
|
| 79 |
+
(fails on the old code, passes on the new).
|
| 80 |
+
|
| 81 |
+
## Verified fusion path
|
| 82 |
+
|
| 83 |
+
`NativeVisionFusion` works against a **real** encoder (`google/siglip-base-patch16-224` vision
|
| 84 |
+
tower): 196 image tokens + 8 text tokens -> 204-length fused sequence, logits shaped
|
| 85 |
+
`(1, 204, 1000)`, and embeddings change with image content (red-vs-blue delta 0.46). It does
|
| 86 |
+
**not** yet work with the real 1.65 T core.
|
| 87 |
+
|
| 88 |
+
## Test commands
|
| 89 |
+
|
| 90 |
+
```bash
|
| 91 |
+
PYTHONPATH=/workspace/project python3 -m pytest tests/ -q # 6 tests
|
| 92 |
+
cd encoding && PYTHONPATH=$PWD python3 -m pytest test_encoding_dsv4.py -q # 4 tests
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
Requires `torch` (CPU wheel), `torchvision`, `pillow`, `transformers`.
|
|
@@ -6,6 +6,7 @@ existing 1.65T DeepSeek checkpoint is not modified, and a core is only
|
|
| 6 |
accepted when its runtime exposes the required inputs_embeds contract.
|
| 7 |
"""
|
| 8 |
|
|
|
|
| 9 |
from dataclasses import dataclass
|
| 10 |
from typing import Any, Callable
|
| 11 |
|
|
@@ -47,7 +48,13 @@ class NativeVisionFusion(nn.Module):
|
|
| 47 |
if self.image_processor is not None
|
| 48 |
else image
|
| 49 |
)
|
| 50 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 51 |
if hasattr(encoded, "last_hidden_state"):
|
| 52 |
encoded = encoded.last_hidden_state
|
| 53 |
if not isinstance(encoded, Tensor) or encoded.ndim != 3:
|
|
|
|
| 6 |
accepted when its runtime exposes the required inputs_embeds contract.
|
| 7 |
"""
|
| 8 |
|
| 9 |
+
from collections.abc import Mapping
|
| 10 |
from dataclasses import dataclass
|
| 11 |
from typing import Any, Callable
|
| 12 |
|
|
|
|
| 48 |
if self.image_processor is not None
|
| 49 |
else image
|
| 50 |
)
|
| 51 |
+
# Transformers processors return BatchFeature, a UserDict rather than a
|
| 52 |
+
# dict subclass, so a plain isinstance(..., dict) check would pass the
|
| 53 |
+
# processor output positionally into the encoder's input_ids parameter.
|
| 54 |
+
if isinstance(model_input, Mapping):
|
| 55 |
+
encoded = self.vision_encoder(**model_input)
|
| 56 |
+
else:
|
| 57 |
+
encoded = self.vision_encoder(model_input)
|
| 58 |
if hasattr(encoded, "last_hidden_state"):
|
| 59 |
encoded = encoded.last_hidden_state
|
| 60 |
if not isinstance(encoded, Tensor) or encoded.ndim != 3:
|
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
|
|
| 1 |
import torch
|
| 2 |
from torch import nn
|
| 3 |
|
|
@@ -31,3 +33,29 @@ def test_native_image_embedding_fusion_executes_real_tensor_path():
|
|
| 31 |
assert result.text_token_count == 2
|
| 32 |
assert core.last_inputs_embeds.shape == (1, 5, 8)
|
| 33 |
assert result.outputs["attention_mask"].shape == (1, 5)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from collections import UserDict
|
| 2 |
+
|
| 3 |
import torch
|
| 4 |
from torch import nn
|
| 5 |
|
|
|
|
| 33 |
assert result.text_token_count == 2
|
| 34 |
assert core.last_inputs_embeds.shape == (1, 5, 8)
|
| 35 |
assert result.outputs["attention_mask"].shape == (1, 5)
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
class BatchFeatureLikeEncoder(nn.Module):
|
| 39 |
+
"""Encoder whose processor output is a UserDict, as Transformers processors return."""
|
| 40 |
+
|
| 41 |
+
def forward(self, pixel_values):
|
| 42 |
+
return torch.ones(pixel_values.shape[0], 2, 4)
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
class BatchFeatureLikeProcessor:
|
| 46 |
+
def __call__(self, image, return_tensors=None):
|
| 47 |
+
return UserDict({"pixel_values": torch.zeros(1, 3, 16, 16)})
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def test_processor_output_is_unpacked_by_keyword_not_positionally():
|
| 51 |
+
core = TinyCore()
|
| 52 |
+
fusion = build_native_fusion(
|
| 53 |
+
BatchFeatureLikeEncoder(),
|
| 54 |
+
core,
|
| 55 |
+
vision_hidden_size=4,
|
| 56 |
+
cortex_hidden_size=8,
|
| 57 |
+
image_processor=BatchFeatureLikeProcessor(),
|
| 58 |
+
)
|
| 59 |
+
result = fusion(input_ids=torch.tensor([[1, 2]]), image="unused")
|
| 60 |
+
assert result.image_token_count == 2
|
| 61 |
+
assert result.text_token_count == 2
|