Skip to content

Add oxidize-c engine with Gemma 4, MoE support, and CUDA optimizations - #37

Closed
Jackson57279 wants to merge 307 commits into
c-port-1000tpsfrom
master
Closed

Jackson57279 wants to merge 307 commits into
c-port-1000tpsfrom
master

Conversation

@Jackson57279

@Jackson57279 Jackson57279 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary by cubic

Adds a plain-C oxidize-c inference engine with Gemma 4 and MoE support, plus CUDA resident-forward optimizations and AL-family quantization across Rust/C++/C for faster, smaller GGUF serving.

New Features

  • oxidize-c C11 runtime: GGUF loader/writer, BPE tokenizer, transformer forward, batched decode, paged KV cache with scheduler, autotune planner, 16 CLI subcommands, and an OpenAI-compatible HTTP/WebSocket server with SSE streaming.
  • Gemma 4 (dual-geometry attention, SWA, IQ4_XS), qwen3.5 hybrid GDN/MTP, MoE router + expert stacks, and DeepSeek MLA across ports. Full forward passes now cover GLM/Hunyuan, Phi, and GPT-2/NeoX/Falcon.
  • Speculative decoding (draft/verify, DFlash, Eagle-3, tree), flash attention, Q8 KV cache, LRU prefix + persistent context caches, attention sinks, and YaRN context scaling.
  • Samplers: Mirostat, typical-p, tail-free, min-p, beam/contrastive search, and grammar constraints for structured output.
  • CUDA backend keeps weights quantized in VRAM (MMQ kernels) with fused kernels, CPU-GPU offload, and OXK AVX2/AVX-512 GEMV paths.
  • AL-family quants (AL5/AL6/AL8/AL5_XS) plus IQ formats (IQ2_XS, IQ2_S, IQ4_NL) wired through oxidize-core, oxidize-cpp, and de/quant pipelines.
  • Tooling: AL targets in oxidize-convert/oxidize-quantize, merge strategies, Wanda pruning, SafeTensors→GGUF conversion, HF Hub downloads with resume, model registry, and perplexity evaluation.
  • Server stack adds /v1/embeddings and /v1/responses routes, auth/rate-limit/metrics middleware, LoRA adapter inference, and a WebSocket realtime API.
  • oxidize-finetuning gains generation, a self-train loop, and richer LoRA export/CLI wiring.
  • Ops: pipeline/tensor parallelism, gossip/election/ring mesh, layer-wise inference, GPU cluster, WASM bridge, Modal deploy/bench, Colab notebooks, and CI workflows.

Bug Fixes

  • Correct IQ1_S grid, IQ4_NL block sizing, Q3_K/Q5_K dequant pointer math, and AL8/AL6/AL5_XS block widths.
  • Robust Gemma 4 load, stable MoE expert slicing, consistent speculative KV state, and paged scheduler accounting.
  • Hardened server input parsing, streaming detokenization UTF-8 boundaries, and tokenizer edge cases.
  • oxidize-cpp NUMA caps to physical cores; security advisories patched via vendored libp2p crates.

Written for commit df9f876. Summary will update on new commits.

Review in cubic

@cursor

cursor Bot commented Jul 14, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 635f2ae231

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread oxidize-c/server.c Outdated
Comment on lines +524 to +527
if (strncmp(req, "GET /v1/realtime", 16) == 0 &&
strcasestr(req, "Upgrade: websocket")) {
ws_session(fd, req, m, tok, temperature, draft_k);
continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Enforce API keys before serving generation routes

When --serve is bound to anything reachable beyond localhost, setting OXIDIZE_API_KEY only gates process startup; this request path never checks the Authorization header before accepting WebSocket sessions or the POST completion routes below. That makes the advertised API-key protection ineffective and allows any client that can reach the port to run inference. Add a header check against OXIDIZE_API_KEY/OXIDIZE_API_KEYS before dispatching /v1/realtime, /v1/chat/completions, and /v1/completions while leaving /health unauthenticated if desired.

Useful? React with 👍 / 👎.

Comment on lines +483 to +484
if (layer.ffn_gate_expert_list.size() != config_.num_experts) {
throw std::runtime_error("incomplete split-expert tensor set for " + p);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip split-expert validation for dense MoE blocks

For MoE checkpoints with leading dense layers (the Hunyuan/DeepSeek layouts this change adds support for), config_.num_experts is nonzero but the early blk.* layers legitimately have dense ffn_gate/up/down weights and no _exps or ffn_gate.<i> tensors. This newly added completeness check still runs on those dense layers, the split-expert loop breaks at expert 0, and model construction throws incomplete split-expert tensor set before the dense layer can be used. Only enforce split-expert completeness after detecting a router/expert layer, or skip it for leading_dense_layers.

Useful? React with 👍 / 👎.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

24 issues found across 106 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="scripts/prime-gemma4-31b-int4/nginx-dual.conf">

<violation number="1" location="scripts/prime-gemma4-31b-int4/nginx-dual.conf:15">
P0: The ALPHA load balancer will return 502 for every request because 127.0.0.1 in `gemma4-lb` is the Nginx container's loopback, not the host where ports 8000 and 8001 are bound. Align the containers on a shared network (or use host networking for Nginx) before using these upstream addresses.</violation>
</file>

<file name="oxidize-core/src/model/inference.rs">

<violation number="1" location="oxidize-core/src/model/inference.rs:267">
P1: CUDA fused attention ignores YaRN for models configured with `rope.scaling.type = "yarn"`, producing different positional embeddings from the CPU path; extending the CUDA RoPE interface or disabling the fused path when YaRN is active would preserve correctness.</violation>
</file>

<file name="scripts/prime-qwen35-self-train/strip_branding.py">

<violation number="1" location="scripts/prime-qwen35-self-train/strip_branding.py:46">
P1: Rendering `tokenizer_config.json` fails whenever its template uses `qwythos_identity`: this branch deletes the definition but leaves the references undefined. Applying the same `t.replace("qwythos_identity", '""')` transformation used for `chat_template.jinja` keeps both HF template copies executable.</violation>
</file>

<file name="scripts/prime-qwen35-self-train/run-self-train.sh">

<violation number="1" location="scripts/prime-qwen35-self-train/run-self-train.sh:69">
P1: A rerun can upload an incomplete adapter: the watcher sees a previous run's `finished` marker because this command appends to the shared log. Truncating the log for each run or using a run-specific completion marker would keep uploads tied to the current training job.</violation>
</file>

<file name="oxidize-core/src/compute/quantization/quant_simple.rs">

<violation number="1" location="oxidize-core/src/compute/quantization/quant_simple.rs:122">
P1: Q4_0 CUDA/ROCm GEMV now returns incorrect dot products for the newly encoded blocks because the quantizer uses split-half ordering while `gemv_q4_0_kernel` still uses interleaved vector indices. Updating the kernel indexing (including the shared ROCm build) would keep GPU results consistent with `dequantize_q4_0_scalar`.</violation>
</file>

<file name="scripts/gemma4_31b_al_remote.sh">

<violation number="1" location="scripts/gemma4_31b_al_remote.sh:21">
P1: User-controlled path, repository, and quant arguments are interpolated into remote shell command text without serialization, allowing shell-command injection on the target host. Passing a quoted/encoded payload over stdin or shell-escaping every SSH argument would preserve values without interpreting them as commands.</violation>

<violation number="2" location="scripts/gemma4_31b_al_remote.sh:53">
P0: The generated AL files cannot be valid full-model quants because this command feeds only shard 1 to the GGUF writer even though the downloaded model has two shards. The quantizer needs a multi-shard-safe input path/writer before this script can publish usable models.</violation>
</file>

<file name="scripts/prime-qwen35-self-train/setup-node.sh">

<violation number="1" location="scripts/prime-qwen35-self-train/setup-node.sh:54">
P1: Setup currently aborts during the build step because `oxidize-finetuning` is a documented failing crate in this checkout. A working finetuning revision or a fixed crate needs to be used before this one-time setup can complete.</violation>
</file>

<file name="scripts/publish_gguf_remote_hf.sh">

<violation number="1" location="scripts/publish_gguf_remote_hf.sh:12">
P1: The exit trap recursively deletes whatever `STAGING` points at, including pre-existing user data when `STAGING` is supplied or `.hf-staging` already exists. A unique `mktemp` subdirectory should be created and only that run directory cleaned up.</violation>

<violation number="2" location="scripts/publish_gguf_remote_hf.sh:36">
P1: A caller-controlled `HF_REPO` is interpolated into Python source, so a crafted repository argument can execute arbitrary Python locally. Passing the value as a Python argv/environment value with a quoted heredoc avoids code injection.</violation>

<violation number="3" location="scripts/publish_gguf_remote_hf.sh:52">
P1: The final publication step can report success while the README upload failed, because its fallback performs no HF operation and returns zero; it also creates the bogus `null` file on success. A single `--readme-only` call without the no-op fallback would preserve the failure status.</violation>
</file>

<file name="oxidize-cpp/src/tensor_cpu.cpp">

<violation number="1" location="oxidize-cpp/src/tensor_cpu.cpp:694">
P1: Quantized inference can crash on AVX2/F16C CPUs that lack FMA because this gate enables code containing `_mm256_fmadd_ps` without checking FMA support. Include `__builtin_cpu_supports("fma")` in the runtime condition, or provide a non-FMA implementation.</violation>
</file>

<file name="scripts/prime-qwen35-self-train/upload-hf.sh">

<violation number="1" location="scripts/prime-qwen35-self-train/upload-hf.sh:6">
P1: When `OUT_DIR` is customized without an explicitly exported `TRAIN_OUT`, the shell waits on the customized output but Python falls back to `$HOME/models/qwen35-9b-agent/self-train-out`; it can therefore upload an older/default run instead of the current adapter. Exporting the computed `TRAIN_OUT` or passing the shell value directly into Python would preserve the selected output path.</violation>
</file>

<file name="oxidize-c/tokenizer.c">

<violation number="1" location="oxidize-c/tokenizer.c:257">
P1: SentencePiece/Gemma prompts are segmented by local max-score pair merges here, not by the global score-maximizing unigram segmentation. A vocabulary can prefer `a+bc` overall while the heap commits to `ab`, producing different token IDs for the same prompt; the C tokenizer should use unigram/Viterbi segmentation.</violation>
</file>

<file name="notebooks/coding_agent_sft_datasets.ipynb">

<violation number="1" location="notebooks/coding_agent_sft_datasets.ipynb:241">
P1: The Colab workflow cannot clone its checkout because `/content/oxidize` is already non-empty when this command runs, and the ignored clone failure leaves the subsequent build pointed at that incomplete directory. Cloning into a clean path before creating `OUT_DIR` and checking the command status would make the documented Colab flow executable.</violation>

<violation number="2" location="notebooks/coding_agent_sft_datasets.ipynb:315">
P1: With `RUN_TRAIN=True`, the subprocess fails before self-training starts because `self-train` does not support `--max-tokens`; that option exists for `sft`, not `SelfTrainArgs`. Removing this pair or replacing it with a supported self-train option lets the training workflow run.</violation>
</file>

<file name="oxidize-cpp/src/gguf.cpp">

<violation number="1" location="oxidize-cpp/src/gguf.cpp:451">
P1: Recognizing Hunyuan without routing it through the HF decoder mapper leaves every Hunyuan tensor in its raw name; loading then cannot find required tensors such as `tok_embeddings.weight`. Include all Hunyuan aliases in the `map_tensor_name` decoder branch.</violation>
</file>

<file name="modal_oxidize.py">

<violation number="1" location="modal_oxidize.py:58">
P1: The public `serve` endpoint exits on every standard Modal deployment because the function has no `secrets=[...]` binding, so a local `OXIDIZE_API_KEY` is not present remotely; this also downloads the multi-GB model before failing. Inject the key through a Modal Secret and validate it before calling `ensure_model()`.</violation>
</file>

<file name="scripts/prime-gemma4-31b-int4/setup-node.sh">

<violation number="1" location="scripts/prime-gemma4-31b-int4/setup-node.sh:27">
P1: A pod without a preconfigured NVIDIA Docker runtime fails at the first `docker run --gpus all`, so setup never reaches the model download. The setup needs to install/configure and validate the NVIDIA Container Toolkit, or avoid requesting a GPU for the CPU-only download step.</violation>

<violation number="2" location="scripts/prime-gemma4-31b-int4/setup-node.sh:30">
P0: The INT4 checkpoint download never runs: this image's `vllm serve` entrypoint receives `python3 -c ...` as serve arguments, so the container exits or tries to serve a model named `python3`. Overriding the entrypoint to `python3` is needed for this download step.</violation>
</file>

<file name="scripts/hy3_1m_al_remote.sh">

<violation number="1" location="scripts/hy3_1m_al_remote.sh:27">
P1: Running without `HF_TOKEN` fails immediately with an unbound-variable error, even though the script explicitly defaults the token to empty. Expanding the optional positional parameter with an unset-safe form, or passing arguments through a safe serialized channel, preserves anonymous downloads.</violation>
</file>

<file name="oxidize-core/src/compute/tensor/kernels/q_kernels.rs">

<violation number="1" location="oxidize-core/src/compute/tensor/kernels/q_kernels.rs:1757">
P1: IQ4_NL GEMV returns incorrect results for every nontrivial block because the activation indices do not match the format's two-half weight layout. Pair each packed weight byte with Q8 positions `i` and `i + 16` instead of `2*i` and `2*i + 1`.</violation>
</file>

<file name="scripts/bench_iq_remote.sh">

<violation number="1" location="scripts/bench_iq_remote.sh:186">
P1: The Rust leg will not benchmark ordinary IQ GGUF models: `--engine standard` is not a supported normal-model engine and falls through to the DFlash loading path, which can fail before producing throughput. Using the supported `inference` engine would run the intended model benchmark.</violation>
</file>

<file name="scripts/prime-gemma4-31b-int4/llamacpp-unsloth.sh">

<violation number="1" location="scripts/prime-gemma4-31b-int4/llamacpp-unsloth.sh:14">
P1: The fallback exits before starting because both expected filenames are wrong for the files downloaded by the setup recipe: the target is `gemma-4-31B-it-qat-UD-Q4_K_XL.gguf` and the MTP drafter is `mtp-gemma-4-31B-it.gguf`; the latter is also excluded by the setup download pattern. Use the repository filenames consistently and include the `mtp-` file in the download step.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic


upstream gemma4_backends {
least_conn;
server 127.0.0.1:8000 max_fails=3 fail_timeout=10s;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P0: The ALPHA load balancer will return 502 for every request because 127.0.0.1 in gemma4-lb is the Nginx container's loopback, not the host where ports 8000 and 8001 are bound. Align the containers on a shared network (or use host networking for Nginx) before using these upstream addresses.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/prime-gemma4-31b-int4/nginx-dual.conf, line 15:

<comment>The ALPHA load balancer will return 502 for every request because 127.0.0.1 in `gemma4-lb` is the Nginx container's loopback, not the host where ports 8000 and 8001 are bound. Align the containers on a shared network (or use host networking for Nginx) before using these upstream addresses.</comment>

<file context>
@@ -0,0 +1,33 @@
+
+    upstream gemma4_backends {
+        least_conn;
+        server 127.0.0.1:8000 max_fails=3 fail_timeout=10s;
+        server 127.0.0.1:8001 max_fails=3 fail_timeout=10s;
+        keepalive 64;
</file context>

Comment thread oxidize-c/server.c Outdated
Comment thread oxidize-c/server.c Outdated
Comment thread oxidize-c/cuda.cu Outdated
Comment thread oxidize-c/cuda.cu Outdated
Comment thread oxidize-c/cuda.cu Outdated
Comment thread oxidize-c/cuda.cu Outdated
Comment thread oxidize-c/cuda.cu Outdated

echo "==> Pre-downloading INT4 QAT checkpoint (~20GB)"
docker run --rm \
--gpus all \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: A pod without a preconfigured NVIDIA Docker runtime fails at the first docker run --gpus all, so setup never reaches the model download. The setup needs to install/configure and validate the NVIDIA Container Toolkit, or avoid requesting a GPU for the CPU-only download step.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At scripts/prime-gemma4-31b-int4/setup-node.sh, line 27:

<comment>A pod without a preconfigured NVIDIA Docker runtime fails at the first `docker run --gpus all`, so setup never reaches the model download. The setup needs to install/configure and validate the NVIDIA Container Toolkit, or avoid requesting a GPU for the CPU-only download step.</comment>

<file context>
@@ -0,0 +1,49 @@
+
+echo "==> Pre-downloading INT4 QAT checkpoint (~20GB)"
+docker run --rm \
+  --gpus all \
+  -v "$HF_HOME:/root/.cache/huggingface" \
+  -e HF_TOKEN="${HF_TOKEN:-}" \
</file context>

theta: f32,
output: &mut [f32],
) -> Result<(), crate::tensor::RopeError> {
apply_rope_f32_yarn(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1: CUDA fused attention ignores YaRN for models configured with rope.scaling.type = "yarn", producing different positional embeddings from the CPU path; extending the CUDA RoPE interface or disabling the fused path when YaRN is active would preserve correctness.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At oxidize-core/src/model/inference.rs, line 267:

<comment>CUDA fused attention ignores YaRN for models configured with `rope.scaling.type = "yarn"`, producing different positional embeddings from the CPU path; extending the CUDA RoPE interface or disabling the fused path when YaRN is active would preserve correctness.</comment>

<file context>
@@ -232,11 +248,33 @@ impl Default for InferenceConfig {
+        theta: f32,
+        output: &mut [f32],
+    ) -> Result<(), crate::tensor::RopeError> {
+        apply_rope_f32_yarn(
+            input,
+            position,
</file context>

Jackson57279 and others added 27 commits July 20, 2026 19:04
Add Gemma-specific forward path:
- GeGLU activation: gelu(gate) * up (erf-based exact GeLU), used by Gemma's
  FFN instead of SwiGLU. Added oc_geglu_inplace_f32, oc_gelu_exact_f32,
  oc_gelu_approx_f32 to activation.h/c.
- Norm scaling: Gemma multiplies RMSNorm output by sqrt(n_embd). Added
  norm_scale field to OcLlamaConfig (default 1.0, set to sqrt(n_embd) for
  Gemma). Applied after each RMSNorm call (attn_norm, ffn_norm, final_norm).
- Config detection: uses_geglu and norm_scale set based on arch string
  starting with gemma.
- forward_dense_ffn dispatches between SwiGLU and GeGLU based on config.
  Mistral/Phi share the Llama SwiGLU path by default.

Tests: GeGLU basic (gelu(0)=0, gelu(1)=0.841345), GeGLU vs SwiGLU
differ, Gemma config defaults (norm_scale = sqrt(3072)).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add CUDA backend (OC_CUDA) for NVIDIA GPU deployment (L40S on Modal):
- CUDA kernels: embedding lookup, RMSNorm (shared-mem reduction), matvec
  (one block per row, tree reduction), RoPE (split-halves), SwiGLU/GeGLU,
  per-head attention (online softmax), KV cache write, residual add.
- oc_cuda_init: uploads + dequantizes all weights to device f32, allocates
  KV cache + workspace on GPU.
- oc_cuda_forward: full layer loop on GPU (RMSNorm → QKV → RoPE → KV cache
  → attention → output proj → FFN → residual), final norm + lm_head.
- Makefile: make cuda compiles .cu with nvcc, .c with gcc, links with
  -lcudart. CPU build unaffected (no .cu in LIB_SRCS wildcard).
- oc_cuda_available() runtime check; falls back to CPU when no GPU.

Untested locally (no GPU); designed for Modal L40S deployment.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add YaRN (Yet another RoPE extensioN) for long-context models:
- oc_apply_rope_yarn_f32: smooth ramp interpolation between [0.8, 1.2] ×
  orig_ctx. Beyond orig_ctx × 1.2, positions are scaled by orig_ctx / pos,
  effectively compressing the rotary frequencies for extended context.
- Config: yarn_factor and yarn_orig_ctx fields in OcLlamaConfig. Parsed from
  GGUF metadata rope.scaling.type="yarn" + rope.scaling.factor.
- Forward path dispatches to YaRN RoPE when yarn_factor > 0, normal RoPE
  otherwise. Applied to both Q and K heads.
- Added cfg_str helper for reading string metadata from GGUF.

Tests: YaRN identity within ctx, YaRN differs beyond ctx, YaRN no-op when
factor=0.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Add chat template rendering for proper message formatting:
- ChatML (Qwen/Mistral): <|im_start|>role\ncontent<|im_end|>\n
- Llama-3: <|start_header_id|>role<|end_header_id|>\n\ncontent<|eot_id|>
- Llama-2: [INST] content [/INST] with <<SYS>> system handling
- Gemma: <start_of_turn>role\ncontent<end_of_turn>\n
- Plain text fallback

oc_chat_render_message renders a single message with is_first/is_last flags
for generation prompt injection. oc_chat_render_messages renders a full
conversation. oc_chat_detect auto-selects template from arch string.

Tests: ChatML user message, ChatML assistant prompt, Llama-3 format,
Llama-2 format, Gemma format, multi-message rendering, auto-detect.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…streaming

Add new CLI flags:
- --draft-model: path to draft model for speculative decoding
- --draft-tokens: K draft tokens per step (default 4)
- --quantize: input GGUF path for offline weight quantization
- --output: output GGUF path for quantized model
- --quant-type: target quantization type (Q4_0, Q4_K_M, etc.)
- --stream: enable streaming output mode (SSE)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- Add --backend cpu|cuda flag to CLI args
- Wire oc_cuda_init/forward/free into run_generation
- CUDA forward used for prefill + decode when --backend cuda
- CPU stub (cuda_stub.c) compiled when OC_CUDA not defined
- Fix Makefile: CUDA build excludes cuda_stub.c, compiles .cu with nvcc
- Fix OC_ERR_UNSUPPORTED -> OC_ERR_BACKEND (no unsupported error code)
- Fix unused parameter warning in chat.c

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…ld, and tests

- arena: overflow guards (round_up_pow2 hang, chunk size wrap, fit check,
  dup_n n+1), reset now reuses existing chunks
- vector: multiplication/count overflow guards, self-append aliasing safe
  in push and push_n; error: ctx_format returns full chain length
- tokenizers: DISALLOW_SPECIAL enforced for all kinds, atomic GPT-2 init,
  OOM propagation in interning/training/Viterbi, seg_ids leak, NULL
  role/content validation, strict merge metadata (Rust parity), shared
  utf8_utils.h with WHATWG-correct lossy decode
- gguf/mmap: open_fd validates len vs st_size, aggregate mlock budget for
  split shards, filename scan UB, name-dup OOM propagation, unified file
  no longer claims mmap bytes as freeable
- build: -Iinclude in CPPFLAGS, lint propagates exit status, cuda target
  links -L$(CUDA_HOME)/lib64 -lstdc++; criterion alloc.h delete_arr
  prefix fix + bad_alloc on OOM
- tests: hashtable per-insert key storage, log env-filter coverage,
  mmap oversized-len expectation; cli: declare missing decode_start

307/307 tests passing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d, GPU test, lint, cross-compile

- cpu-build-test: Ubuntu + macOS builds with ASan+UBSan test suite
- static-lib: verify liboxidize-c.a builds correctly
- avx512-build: AVX-512 build for Cascade Lake (matches .121)
- cuda-build: CUDA compile-only build with nvcc (no GPU required)
- gpu-test: Modal T4 GPU inference test (requires Modal secrets)
- lint: clang-tidy, TODO/FIXME check, memory leak pattern check
- cross-compile-arm64: aarch64 cross-compile verification

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
…, bench/min-p/mirostat CLI flags

Samplers:
- Mirostat v2 (surprise-based): oc_mirostat_v2_sample with running mu estimate
- Min-p: filter tokens below min_p * max_p ratio
- CLI flags: --min-p, --mirostat-tau, --mirostat-eta

Vision/multimodal stubs:
- OcVisionConfig/Encoder with CLIP-style ViT config
- oc_vision_encode (stub: returns zeros)
- oc_vision_resize (bilinear), oc_vision_normalize ([-1,1] range)
- OcMultimodalPrompt for text+image embedding fusion

Mesh/distributed stubs:
- OcMesh with peer discovery, broadcast, all-reduce, shard layout
- TP degree sharding (oc_mesh_shard_for_layer)

CLI:
- --bench, --bench-iters flags
- --min-p, --mirostat-tau, --mirostat-eta flags

Tests: vision init/encode/resize/normalize/multimodal, mesh
init/connect/shard/broadcast/allreduce (11 new tests, 324 total).

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- --bench flag: runs N iterations of greedy decode, reports best/avg tok/s
  with per-iteration timing using clock()
- SSE streaming for /v1/completions: detects stream:true in request body,
  returns text/event-stream with data: JSON chunks + data: [DONE]

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- oc_quantize_model: reads input GGUF, dequantizes weight tensors to f32,
  re-quantizes to target type, writes output GGUF with patched tensor types
- Minimal GGUF v3 writer with metadata copying, tensor info patching,
  alignment padding
- --quantize flag wired in CLI (--quantize INPUT --output OUT --quant-type Q4_K_M)
- oc_quantize_parse_type: string→OcGgufQuantizationType via name table
- 7 new tests (type parsing, block sizes), 331 total passing.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
MLA (Multi-head Latent Attention):
- OcLlamaConfig: uses_mla, mla_q_lora_dim, mla_kv_lora_dim, mla_q_rope_dim,
  mla_kv_nope_head_dim, mla_v_head_dim fields
- OcLlamaLayer: mla_q_a, mla_q_b, mla_kv_a_mqa, mla_k_b, mla_v_b weight views
  + mla_q_a_norm, mla_kv_a_norm RMSNorm weights
- OcLlamaSession: mla_c_q, mla_c_kv, mla_q_full, mla_kv_compressed temporaries
- forward_mla_attention: Q down→norm→up, KV down→norm, per-head K/V up-proj,
  decoupled RoPE on q_pe/k_pe, online-softmax attention per head
- Config parsing: deepseek2.attention.key_length_mla + lora_q/lora_kv/key_length_rope
- Tensor loading: attn_q_a, attn_q_a_norm, attn_q_b, attn_kv_a_mqa,
  attn_kv_a_norm, attn_k_b, attn_v_b
- MLA KV cache sized n_head*head_dim (per-head, no GQA sharing)

Model inspect mode:
- --inspect flag: prints GGUF header, metadata, tensor table (first 20),
  total file size, architecture detection

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcBatchSession: processes up to OC_MAX_BATCH_SEQ=16 sequences per forward pass
- OcBatchSeq: per-sequence token, position, logits output, active flag
- oc_batch_forward: iterates active sequences through shared weight workspace
  (better cache locality than separate sessions)
- KV cache sized per-sequence: [n_layer][n_ctx][kv_row_floats * max_seqs]
- Reuses forward_layer for each sequence (MLA excluded in batch for now)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcStreamingDetokenizer: incremental token-by-token decoding with pending
  byte buffer for partial UTF-8 sequences split across token boundaries
- oc_streaming_detok_push: decode one token, emit complete UTF-8 delta,
  buffer incomplete tail
- oc_streaming_detok_flush: emit remaining pending bytes at end of stream
- UTF-8 sequence validation (lead byte + continuation byte checking)
- Thread-local combined buffer for zero-copy delta emission

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OC_SAMPLER_TYPICAL_P (6): locally typical sampling - computes entropy H,
  scores tokens by |surprise - H|, keeps tokens with lowest deviation
  until cumulative probability reaches typical_p threshold
- OC_SAMPLER_TAIL_FREE (7): tail-free sampling - computes second derivative
  of sorted probabilities |d2(p)|, normalizes, accumulates until z-threshold
- OcSamplerConfig: added typical_p and tail_free_z fields

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcLlamaSession: kv_quantized flag + kv_k_q8/kv_v_q8 int8 caches + per-block
  f16 scales (kv_k_scale/kv_v_scale)
- kv_quantize_q8: per-block (32-element) asymmetric quantization with f16 scale
- kv_dequantize_q8: reverse quantization for attention computation
- Q8 KV cache halves memory usage at a small quality cost
- Allocated on session init (not yet wired into forward path)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcLlamaConfig: sliding_window (window size) + sliding_window_pattern
  (1=all global, 2=alternating global/sliding)
- Config parsing: reads attention.sliding_window from GGUF metadata
  for Gemma2 models, sets pattern=2 (alternating)
- attention_head: skips tokens outside the sliding window for layers
  matching the alternating pattern (layer % pattern == 1)

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcAttnDumper: env-gated (OXIDIZE_TRACE_VALS / OXIDIZE_TRACE_FWD) per-layer
  attention weight + logits dump to disk
- oc_attn_dump_f32: writes float arrays as .f32 binary files
- oc_attn_dump_logits: writes logits per forward step
- oc_attn_dump_set_context: sets step/layer for subsequent dumps
- 3 new tests (init, dir, context), 334 total passing.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcGrammarConstraint: JSON, choice, and regex (stub) constraint types
- JSON mode: tracks string/escape state, filters structural chars outside
  strings, validates escape sequences inside strings
- Choice mode: allows tokens matching any of a set of literal strings,
  tracks match position, marks finished when a choice is completed
- oc_grammar_allows_token: simulates token advancement to check validity
- oc_grammar_advance: updates state after token acceptance
- oc_grammar_is_satisfied: checks if constraint is met (JSON complete, choice done)
- 7 new tests (init, JSON structural, string mode, choice, reset, satisfied, token), 341 total passing.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
- OcPrefixCache: LRU cache of KV snapshots keyed by FNV-1a token hash
- oc_prefix_hash_tokens / oc_prefix_hash_continue: incremental FNV-1a hashing
- oc_prefix_cache_lookup/store/evict/clear: standard LRU operations
- OcCachedPrefix: hash, n_tokens, opaque kv_data, last_used timestamp
- OcPrefixCacheStats: entry count, total KV bytes
- 7 new tests (hash, incremental, init, store/lookup, evict, clear, stats), 348 total.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Timing:
- Replace clock() (CPU time) with clock_gettime(CLOCK_MONOTONIC) (wall clock)
- Benchmark mode: now reports decode tok/s AND prefill tok/s per iteration
- Generation mode: wall-clock tok/s reporting

Perplexity:
- oc_perplexity_evaluate: tokenizes text, runs forward, computes cross-entropy
  loss at each position, returns perplexity (2^avg_nll)
- oc_perplexity_evaluate_file: reads text from file for evaluation
- --perplexity / --ppl CLI flag: runs perplexity evaluation on prompt or file
- OcPerplexityResult: ppl, avg_nll, total_nll, n_tokens, eval_time, tok/s

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Jackson57279 and others added 19 commits August 16, 2026 00:10
Disable fused multiply-add in CFLAGS, compare OXK results within 1 ULP,
and drop calls to missing K-quant multi kernels. Load logs that LongCat
n-gram tensors are unused and that MLA/LongCat skip batched prefill.
Gemma 4 no longer gets a second RMS scale in the batch path. Remove
the committed debug journal.

Co-authored-by: Cursor <cursoragent@cursor.com>
CORS is no longer hardcoded to *; extra headers come from middleware.
Generation errors return NULL so handlers emit 500 instead of an empty
200, and repeat penalty receives prompt token history. Disable fused
multiply-add so OXK results match the scalar reference.

Co-authored-by: Cursor <cursoragent@cursor.com>
LongCat/MLA/prefill/TUI land on the oxidize-c v2 branch. Serving-file
conflicts keep the longcat-c SSE auth and CORS extra-header path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Install CORS and stream auth before workers start, reject oversized
header blocks, and clamp completion history to remaining context.
Stream rejections now hit metrics/audit. MTP copies prefix state,
records last_hidden without logits, uses absolute RoPE, and null-checks
the model. Qwen3.6 joins the loader list; AVX-512 Q8_K quant requires
DQ/VL; attention ISA detect is pthread_once; CUDA CFLAGS keep
-ffp-contract=off.

Co-authored-by: Cursor <cursoragent@cursor.com>
GPT-J GGUFs still died in oc_llama_load after parse_config accepted them.
The sampler chain still handed Mirostat v1 a NULL RNG after the function gained a caller state.

Co-authored-by: Cursor <cursoragent@cursor.com>
A failed pthread_create left workers on stack-owned state. Completions treated a missing model pointer as 500. JSON unquote broke on escaped backslash. Llama GGUFs always used Llama-3 markup.

Co-authored-by: Cursor <cursoragent@cursor.com>
CPU ASan tests failed because a missing prompt never reached 400 once a NULL model pointer returned 503. Nested stream-in-text also expected 500 for that same placeholder state.

Co-authored-by: Cursor <cursoragent@cursor.com>
Windows CI clippy -D warnings failed on Q4_K/Q8_K block walks after stable 1.98 started treating constant-size chunks_exact as an error.

Co-authored-by: Cursor <cursoragent@cursor.com>
Workspace lint on stable 1.98 fails ~90 constant-size chunks_exact sites in oxidize-core. Allow the lint (unknown on 1.97) instead of a mechanical rewrite on this C-port PR.

Co-authored-by: Cursor <cursoragent@cursor.com>
Ubuntu lint still failed after the core crate allow: oxidize-merge byte blends, oxidize-quantize imatrix parse, and OXK benches are separate crates.

Co-authored-by: Cursor <cursoragent@cursor.com>
Ubuntu lint failed on oxidize-core lib tests: Clippy now denies filling a slice with a for-loop. Allow the lint crate-wide and use fill in the video temporal test.

Co-authored-by: Cursor <cursoragent@cursor.com>
CI fmt --check on 1.98 splits the crate-level unknown_lints / chunks_exact / manual_slice_fill allow onto multiple lines.

Co-authored-by: Cursor <cursoragent@cursor.com>
cargo-deny on Ubuntu fails advisories: epoch 0.9.18 has an invalid-pointer Display impl. Update to >=0.9.20.

Co-authored-by: Cursor <cursoragent@cursor.com>
GPT-J now has an interleaved-RoPE forward path instead of GPT-2 WPE.
Chat templates prefer tokenizer.chat_template, JSON unescapes \\r\\b\\f\\uXXXX,
Mirostat v2 uses chain RNG, chat 400 precedes 503, and Q4_K/Q8_K walks
use chunks_exact so a short tail does not panic.

Co-authored-by: Cursor <cursoragent@cursor.com>
CI fmt --check rejected the multi-line iterator chain after switching back from as_chunks.

Co-authored-by: Cursor <cursoragent@cursor.com>
Homebrew Criterion ran tests in parallel under ASan and leaked HTTP
server threads when stream assertions aborted. Run one job on Darwin,
always join the test server, and cap macOS CI tests at 20 minutes.

Co-authored-by: Cursor <cursoragent@cursor.com>
The Homebrew Criterion + ASan run does not finish on macos-latest
(6h cancel, then a 20m timeout with the runner still inside
test_runner). Ubuntu keeps the full sanitizer suite.

Co-authored-by: Cursor <cursoragent@cursor.com>
oxidize-c v2: modular C11 port, threaded forward pass, kernel correctness fixes
Comment thread oxidize-c/tests/test_qwen35_fixture.c Fixed
Comment thread oxidize-c/src/mesh/k8s.c Fixed
Comment thread oxidize-c/src/mesh/k8s.c Fixed
cursoragent and others added 7 commits August 28, 2026 07:53
Cap speculative draft-step and top-k Vec allocations so untrusted
config values cannot request unbounded capacity. Stop writing
Kubernetes env and SA token material from getenv/secrets onto
plaintext sockets; validate API host/port and send Host from
getpeername, attaching the bearer token only on loopback. Drop
stat-then-unlink in the Qwen 3.5 fixture test in favor of the
already-open GGUF backing length.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
_POSIX_C_SOURCE 200809L does not expose getnameinfo size macros on
this toolchain; provide the POSIX defaults so k8s.c compiles.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
A 1024 clamp changed sampling for vocab > 1024. Cap allocation with a
1,048,576 constant bound and return InvalidTopK above that so CodeQL
still sees a sanitizer without shrinking normal top_k.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
Zero token and request buffers on every oc_k8s_scale exit with a
volatile wipe so the bearer string does not linger. Save and restore
OC_K8S_API_URL / KUBERNETES_SERVICE_HOST around tests that mutate them.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
Keep requested top_k: k<=1024 uses an O(n log k) min-heap so
with_capacity stays CodeQL-bounded; larger k sorts the full
distribution then truncates instead of O(n*k) min_by scans.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
Strip [::1]-style brackets from OC_K8S_API_URL before DNS. HTTP Host
still uses getpeername, which already emits RFC 3986 brackets.

Co-authored-by: Jackson  <Jackson57279@users.noreply.github.com>
…ng-c1df

Fix GitHub Code Scanning (CodeQL) allocation, k8s, and TOCTOU alerts
let mut indexed_probs = if let Some(top_k) = top_k_limit {
let mut raw_sum = 0.0_f32;
let mut top_candidates: Vec<(usize, f32)> = Vec::with_capacity(top_k);
let mut heap: BinaryHeap<Reverse<TopKCandidate>> = BinaryHeap::with_capacity(top_k);
@cursor

cursor Bot commented Aug 28, 2026

Copy link
Copy Markdown

Review: what this is, how it works, what to steal

What it is. This PR is inverted. Head is master and base is c-port-1000tps, so GitHub is proposing to dump current master (~307 commits, 730 files) onto an old C-port experiment branch. It is not a feature PR into master.

How it works. c-port-1000tps diverged before the modular C rewrite. Everything this diff appears to “add” (Gemma 4, MoE, CUDA resident-forward, AL-family quants, OpenAI server, LongCat-in-C) already landed on master through later merges:

The “updated today” activity is CodeQL re-running because master moved (#42), not new work on this branch.

Steal. Nothing unique versus current master. Do not merge this direction.

Closing as no merge intent: wrong base/head, superseded, conflicting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants