Skip to content

Carry ggml-org#25731 (TML Inkling) merged onto b10630 - #108

Closed
danielhanchen wants to merge 20 commits into
inkling-25731-upstream-basefrom
inkling-25731-b10630
Closed

Carry ggml-org#25731 (TML Inkling) merged onto b10630#108
danielhanchen wants to merge 20 commits into
inkling-25731-upstream-basefrom
inkling-25731-b10630

Conversation

@danielhanchen

Copy link
Copy Markdown
Member

ggml-org/llama.cpp#25731 stopped merging onto the aged base tag. This branch is c44c9a11a7 with b10630 merged into it and the five conflicts resolved by hand, so the pin set merges again. The base branch is b10630 itself, so the diff here is only the Inkling work, matching the arrangement used by #70, #91 and #99.

The conflicts

ggml/include/ggml-rpc.h - two independent bumps of different fields. Upstream af5172627d took minor 0 to 1 (use_count replacing padding[4], a backward-compatible wire change); the PR took patch 0 to 1, because inserting GGML_OP_FLASH_ATTN_EXT_BANDED mid-enum ggml_op renumbers rpc_tensor.op, which is serialised. Resolved to 5.1.1 and static_assert(GGML_OP_COUNT == 102). History confirms patch is only reset on a major bump, never on a minor one, so incrementing both independently is the existing convention. Verified the merged enum really does have 102 ops.

ggml/src/ggml-backend-meta.cpp - both sides append a new lambda at the same anchor. Kept upstream's rewritten handle_flash_attn_ext verbatim (it carries a real src[4] to src[3] fix plus new mirrored and kv_mirrored split paths that the PR's older copy does not know about), then the PR's handle_flash_attn_ext_banded, then upstream's handle_lightning_indexer. Three disjoint handlers, all three switch cases kept.

ggml/src/ggml-cuda/ggml-cuda.cu - the only genuinely overlapping hunk. Upstream d9b6be07d0 hoists cublasHandle_t cublas_h = ctx.cublas_handle(); and rewrites the call sites; the PR wraps the same cublasSgemm in an if (f32_pedantic) branch. Resolved to the PR's branch structure using upstream's cublas_h in both arms. The three cublasGemm*Ex sites git auto-merged were then re-checked by hand: each must carry upstream's cublas_h and the PR's cu_gemm_algo, and all five call sites do.

src/llama-model-saver.cpp - purely additive fall-through labels. Kept upstream's GRANITE_SWA and DOTS3NOTE alongside the PR's INKLING.

tests/test-llama-archs.cpp - the one that needed care. Upstream bf0a29cc16 deleted the LLM_ARCH_DEEPSEEK4 skip because DSv4 is now testable; the PR anchored its INKLING skip to that deleted block. Keeping both sides would have resurrected the skip and silently un-tested DeepSeek 4 while still compiling and still passing CI. Kept only the INKLING skip, relocated to the surviving anchor.

Confirmed on the built binary that this is right:

| deepseek4 | NVIDIA B200 | MoE   | OK (8.29e-08) | OK   |
| inkling   | NVIDIA B200 | Dense | SKIP          | SKIP |

DeepSeek 4 runs, matching the bare base tag; Inkling skips, matching the PR's intent.

Two extra commits

tools/mtmd/clip.cpp did not compile against the base. Upstream 56db501e7 ("mtmd: use pillow-accurate algo", ggml-org#27594) made every resize algo Pillow-accurate, so RESIZE_ALGO_BICUBIC_PILLOW became redundant and was deleted, with each call site converted to RESIZE_ALGO_BICUBIC. The PR's Inkling vision branch still used the old name, and since the PR never touched the enum there was no conflict to flag it:

error: 'RESIZE_ALGO_BICUBIC_PILLOW' was not declared in this scope

Applied the same conversion upstream applied everywhere else.

Out-of-bounds write in ggml_flash_attn_ext_banded. ggml/src/ggml.c had:

memcpy(result->op_params + 16, &rel_extent, sizeof(rel_extent));

op_params holds 16 int32_t, so index 16 is one past the end. Measured offsets confirm where the 8 bytes land:

op_params elements     = 16
offsetof(op_params)    = 84
op_params + 16 (bytes) = 148
offsetof(flags)        = 148

It writes straight onto ggml_tensor::flags. With the rel_extent = 8 the PR's own tests use, that sets GGML_TENSOR_FLAG_LOSS on every banded attention node. The value is never read back: fattn-banded.cu and fattn-mma-f16.cuh both derive the extent from rel_logits->ne[0], and that memcpy is the only reference in the tree. Deleted it.

Verification

Built in the nightly's configuration (GGML_BACKEND_DL=ON, GGML_CPU_ALL_VARIANTS=ON, GGML_RPC=ON, GGML_CUDA=ON, tools + server), plus LLAMA_BUILD_TESTS=ON which the nightly does not use. Everything was run against the bare b10630 tag as well, and compared.

  • test-backend-ops test -b CUDA0 -o MUL_MAT,MUL_MAT_ID,FLASH_ATTN_EXT,FLASH_ATTN_EXT_BANDED: base 4998/4998, this branch 5011/5011. Exactly the base set plus the 13 new banded cases, nothing lost.
  • FLASH_ATTN_EXT alone: 2936/2936 on both, so ordinary flash attention is untouched by the resolution.
  • test-flash-attn-bias (this PR's own oracle): every case PASS, covering f32/f16/bf16, GQA, sliding, decode offset, strided rel, batch broadcast, 64 heads, and an offset past INT32_MAX. test-flash-attn-generic-hash: pass.
  • test-llama-archs plus the three test-recurrent-state-rollback variants: pass, same as base.
  • Real weights: unsloth/Inkling-Small-GGUF UD-IQ1_S on a B200, coherent output at 55 tok/s.

Known, not fixed here

  • RPC patch version is not enforced at runtime (negotiate_hello compares major and minor only), so a merged 5.1.1 client will silently talk to a stock 5.1.0 rpc-server with every op after FLASH_ATTN_EXT renumbered. That is upstream's own design gap, but it means merged RPC binaries should not be mixed with stock ones.
  • INKLING is absent from moe_mandatory() in test-llama-archs.cpp and from llm_arch_supports_rs_rollback. Both are benign today (the first is gated behind the test skip, the second is an opt-in whitelist defaulting to false), but both want revisiting if anyone writes the Inkling fixture params.

Once ggml-org#25731 lands upstream or a base tag carries it, the pin should move back to the upstream commit and this branch can be deleted.

danielhanchen and others added 18 commits July 18, 2026 08:09
Hybrid attention model: 55 sliding-window plus 11 global layers, banded
content-dependent relative position bias instead of RoPE, per-layer short
convolution state, fine-grained MoE (256 experts top-6 plus 2 shared),
attention log-scaling past 128K, 1M context.

Includes the GGML_OP_FLASH_ATTN_EXT_BANDED operator (CPU and CUDA, fused
into the MMA flash attention kernel with an fp16 accumulator overflow
guard), HF to GGUF conversion, chat template with typed content block
parsing (interleaved thinking, narration and tool calls), mmproj vision
and audio support, and backend op tests at production shapes.
# Conflicts:
#	ggml/src/ggml-cuda/mmq.cuh
#	src/llama-model-saver.cpp
#	src/llama-vocab.h
Upstream 910196f renamed common_chat_params::thinking_end_tag to
thinking_end_tags and changed it from std::string to a vector, so
data.thinking_end_tag = END_MESSAGE no longer compiles.
# Conflicts:
#	src/llama-arch.cpp
# Conflicts:
#	ggml/include/ggml-rpc.h
#	ggml/src/ggml-backend-meta.cpp
#	ggml/src/ggml-cuda/ggml-cuda.cu
#	src/llama-model-saver.cpp
#	tests/test-llama-archs.cpp
op_params holds 16 int32_t, so op_params + 16 is one past the end and the
8 byte write lands on ggml_tensor::flags. Nothing reads it back: the CUDA
kernel and the mma path both take rel_extent from rel_logits->ne[0].
Upstream 56db501 (ggml-org#27594) made every resize algo Pillow-accurate and
folded RESIZE_ALGO_BICUBIC_PILLOW into RESIZE_ALGO_BICUBIC, converting
each call site. The inkling vision branch is the same conversion.

@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: 60007bad63

ℹ️ 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 ggml/include/ggml.h
GGML_OP_FILL,

GGML_OP_FLASH_ATTN_EXT,
GGML_OP_FLASH_ATTN_EXT_BANDED,

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 Preserve existing RPC opcode values

Placing the new operation between FLASH_ATTN_EXT and FLASH_ATTN_BACK renumbers every subsequent value serialized in rpc_tensor.op. When either side is still version 5.1.0, negotiate_hello() accepts the connection because it compares only major and minor versions, so remote graphs can deserialize these values as different operations and fail or compute incorrect results. Append the new operation after existing values, or make negotiation reject incompatible patch versions.

Useful? React with 👍 / 👎.

Comment thread tests/CMakeLists.txt
Comment on lines +293 to +295
add_executable(test-flash-attn-bias test-flash-attn-bias.cpp)
target_link_libraries(test-flash-attn-bias PRIVATE ggml)
add_test(NAME test-flash-attn-bias COMMAND test-flash-attn-bias)

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 Reuse existing tests instead of adding standalone files

Unless maintainers explicitly approved these additions, remove the new test-flash-attn-bias.cpp and test-flash-attn-generic-hash.cpp targets and fold essential coverage into existing test infrastructure such as test-backend-ops.cpp; the repository specifically prohibits adding files under tests/* without maintainer approval.

AGENTS.md reference: AGENTS.md:L84-L87

Useful? React with 👍 / 👎.

@danielhanchen

Copy link
Copy Markdown
Member Author

Closing. The pin in scripts/unsloth/pr-set.json still points at this branch's head, and the nightly merges pinned commits regardless of PR state, so the release is unaffected. The commit is also mirrored to refs/pins/<sha>, so it survives even if the branch is deleted.

Note that repin.py skips closed PRs, so this pin will no longer be repinned automatically when the base tag moves; it will need a manual merge once it stops applying.

# Conflicts:
#	ggml/include/ggml-rpc.h
@danielhanchen danielhanchen reopened this Aug 27, 2026

@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: 2c5b0007bc

ℹ️ 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 tools/mtmd/mtmd-image.cpp
Comment on lines +483 to +485
mtmd_inkling_image_preproc_out mtmd_image_preprocess_inkling(
const clip_image_u8 & img,
resize_algo algo) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Remove the unused duplicate Inkling preprocessor

Remove this internal API and its companion output struct: a repo-wide search finds no caller of mtmd_image_preprocess_inkling, while the runtime uses mtmd_image_preprocessor_inkling::preprocess below. The two implementations already differ in resize precision, normalization, and BF16 rounding, so retaining both adds about 75 lines of dead preprocessing logic that can drift further and mislead future callers about which behavior is authoritative.

AGENTS.md reference: AGENTS.md:L80-L80

Useful? React with 👍 / 👎.

@danielhanchen

Copy link
Copy Markdown
Member Author

Superseded by #138, which is the same upstream PR merged onto b10665 with the llama-model.cpp filter_idx conflict resolved. This carry stopped merging once upstream's qwen4exp landed on its anchor line. The branch stays in place.

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.

2 participants