Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 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
44 changes: 41 additions & 3 deletions common/speculative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <map>
Expand Down Expand Up @@ -923,6 +924,9 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {
int32_t block_size = 0;
llama_token mask_token_id = 0;

bool is_dflash2 = false;
int32_t selector_top_k = 0;

// draft-dspark: the draft carries a Markov head and uses an anchor-first block layout
const bool is_dspark;

Expand Down Expand Up @@ -967,6 +971,9 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {
sample_from_anchor = std::strcmp(buf, "true") == 0;
}
}

selector_top_k = llama_model_dflash_selector_top_k(model_dft);
is_dflash2 = selector_top_k > 0;
mask_token_id = llama_vocab_mask(llama_model_get_vocab(model_dft));

LOG_INF("%s: adding speculative implementation '%s'\n", __func__, common_speculative_type_to_str(type).c_str());
Expand Down Expand Up @@ -998,7 +1005,7 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {

// offload draft sampling to the backend
backend_chains.assign(n_seq, nullptr);
if (this->params.backend_sampling) {
if (this->params.backend_sampling && !is_dflash2) {
for (llama_seq_id seq_id = 0; seq_id < (llama_seq_id) n_seq; ++seq_id) {
llama_sampler * chain = llama_sampler_chain_init(llama_sampler_chain_default_params());
llama_sampler_chain_add(chain, llama_sampler_init_top_k(10));
Expand All @@ -1017,7 +1024,8 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {
llama_set_embeddings_layer_inp(ctx_tgt, (uint32_t) target_layer_ids[k], true);
}

llama_set_embeddings_nextn(ctx_dft, true, /*masked*/ true);
// DFlash2 reads its selector lattice from h_nextn and never consumes raw logits.
llama_set_embeddings_nextn(ctx_dft, true, /*masked*/ !is_dflash2);
llama_set_causal_attn(ctx_dft, false); // DFlash needs non-causal attention
}

Expand Down Expand Up @@ -1186,7 +1194,7 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {
i_block_beg[seq_id] = batch.n_tokens;
n_block [seq_id] = n_block_tokens;
for (int32_t i = 0; i < n_block_tokens; ++i) {
common_batch_add(batch, i == 0 ? dp.id_last : mask_token_id, n + i, { seq_id }, true);
common_batch_add(batch, i == 0 ? dp.id_last : mask_token_id, n + i, { seq_id }, !is_dflash2);
}
}

Expand Down Expand Up @@ -1214,6 +1222,36 @@ struct common_speculative_impl_draft_dflash : public common_speculative_impl {

auto & result = *dp.result;

if (is_dflash2) {
const float * lattice = llama_get_embeddings_nextn(ctx_dft);
GGML_ASSERT(lattice && "DFlash2 selector produced no lattice");

int32_t predecessor = 0;
for (int32_t i = 1; i < n_block_tokens; ++i) {
const float * row = lattice + (size_t) (beg + i) * n_embd_dec;
const float * scores = row + selector_top_k + (size_t) predecessor * selector_top_k;

predecessor = (int32_t) std::distance(scores,
std::max_element(scores, scores + selector_top_k));
if (params.p_min > 0.0f) {
// softmax(scores) at the argmax, i.e. 1 / sum(exp(s_k - s_max))
float sum = 0.0f;
for (int32_t k = 0; k < selector_top_k; ++k) {
sum += std::exp(scores[k] - scores[predecessor]);
}
if (1.0f / sum < params.p_min) {
break;
}
}
result.push_back((llama_token) row[predecessor]);
}

if (result.size() < (size_t) params.n_min) {
result.clear();
}
continue;
}

if (is_dspark) {
// DSpark: read from the first draft slot, truncate below the confidence threshold
const float * conf = params.p_min > 0.0f ? llama_get_embeddings_nextn(ctx_dft) : nullptr;
Expand Down
1 change: 1 addition & 0 deletions conversion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"DeepseekV3ForCausalLM": "deepseek",
"DeepseekV32ForCausalLM": "deepseek",
"DFlashDraftModel": "qwen",
"DFlash2DraftModel": "qwen",
"Qwen3DSparkModel": "qwen",
"DSparkDraftModel": "qwen",
"DSparkSpeculator": "qwen",
Expand Down
34 changes: 31 additions & 3 deletions conversion/qwen.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,7 +639,7 @@ class Qwen3_5MoeTextModel(_Qwen35MRopeMixin, _LinearAttentionVReorderBase):
model_arch = gguf.MODEL_ARCH.QWEN35MOE


@ModelBase.register("DFlashDraftModel")
@ModelBase.register("DFlashDraftModel", "DFlash2DraftModel")
@ModelBase.example("z-lab/Qwen3.5-9B-DFlash")
class DFlashModel(Qwen3Model):
model_arch = gguf.MODEL_ARCH.DFLASH
Expand Down Expand Up @@ -678,9 +678,31 @@ def set_vocab(self):
def set_gguf_parameters(self):
super().set_gguf_parameters()

block_size = self.hparams.get("block_size", 16)
self.gguf_writer.add_block_size(block_size)
dflash_config = self.hparams.get("dflash_config", {})
block_size = dflash_config.get("block_size", self.hparams.get("block_size", 16))
self.gguf_writer.add_block_size(block_size)

if "conv_kernel_size" in dflash_config:
self.gguf_writer.add_conv_kernel_size(int(dflash_config["conv_kernel_size"]))
self.gguf_writer.add_conv_group_size(int(dflash_config["conv_group_size"]))
self.gguf_writer.add_selector_rank(int(dflash_config["selector_rank"]))
self.gguf_writer.add_selector_top_k(int(dflash_config["selector_top_k"]))

output_multiplier = dflash_config.get(
"output_multiplier", self.hparams.get("output_multiplier")
)
if output_multiplier is not None:
self.gguf_writer.add_logit_scale(float(output_multiplier))
softcap = dflash_config.get(
"final_logit_softcapping", self.hparams.get("final_logit_softcapping")
)
if softcap is not None and float(softcap) > 0:
self.gguf_writer.add_final_logit_softcapping(float(softcap))
embedding_scale = dflash_config.get(
"input_embedding_scale", self.hparams.get("input_embedding_scale")
)
if embedding_scale is not None:
self.gguf_writer.add_embedding_scale(float(embedding_scale))

target_layer_ids = dflash_config.get("target_layer_ids", [])
if target_layer_ids:
Expand All @@ -706,6 +728,12 @@ def modify_tensors(self, data_torch: Tensor, name: str, bid: int | None) -> Iter
if name == "model.embed_tokens.weight" and not self.hparams.get("has_embed_tokens", True):
return

if name in (
"model.candidate_selector.predecessor_codebook",
"model.candidate_selector.successor_codebook",
):
name += ".weight"

yield from super().modify_tensors(data_torch, name, bid)


Expand Down
100 changes: 100 additions & 0 deletions ggml/src/ggml-cuda/top-k.cu

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

normally we would require CUDA changes to be in a dedicated PR, unless strictly necessary. but just asking if @ruixiang63 @am17an are ok or you want CUDA in a dedicated one?

also, please tell your agents to clean up code comments per agents.md requirements

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The comments are cleaned up in d1a522f.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think it makes sense to include the CUDA kernel changes in this PR, as they are a key selling point of DFlash2. We should also have the CUDA maintainers review the PR.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I could not repro consistent perf improvements on my E2E runs, using speed-bench as the target (cells show avg pred_t/s)

c1 OFF c1 ON c4 OFF c4 ON
DGX Spark 34.53 34.92 (+1.1%) 17.16 17.51 (+2.0%)
B4500 82.53 82.76 (+0.3%) 38.75 37.70 (-2.7%)
Details

Server command (same for all runs, -np set to 1 or 4):

./build_topk_changes/bin/llama-server \
  -m /mnt/share/gguf/unsloth/Qwen3.8-27B-GGUF/Qwen3.8-27B-UD-Q4_K_M.gguf \
  --spec-type draft-dflash \
  -md /mnt/share/gguf/incoai/Qwen3.8-27B-DFlash2-GGUF/Qwen3.8-27B-DFlash2-Q4_K_M.gguf \
  --spec-draft-n-max 7 \
  -bs \
  --load-mode dio \
  -np 1|4

Bench command (same for all runs):

python tools/server/bench/speed-bench/speed_bench.py \
  --url localhost:8080 --bench qualitative --osl 256 --concurrency 1|4 --limit 8

88 samples total, 8 per category. OFF/ON = topk fusion change disabled/enabled in the server build.

DGX Spark

Cells: avg pred_t/s / avg latency.

category c1 OFF c1 ON c4 OFF c4 ON
coding 34.74 / 10.099s 34.90 / 10.154s 16.59 / 21.958s 17.42 / 20.930s
humanities 33.30 / 9.276s 33.26 / 9.276s 16.05 / 19.511s 16.24 / 19.355s
math 36.45 / 7.443s 36.31 / 7.468s 18.06 / 15.602s 17.96 / 16.026s
qa 32.04 / 7.901s 32.40 / 7.828s 15.23 / 16.724s 15.00 / 16.658s
rag 37.23 / 7.303s 37.84 / 7.197s 16.96 / 15.318s 17.99 / 15.302s
reasoning 34.36 / 7.629s 34.73 / 7.548s 17.02 / 16.106s 17.31 / 16.118s
stem 33.95 / 7.708s 34.77 / 7.529s 16.12 / 16.851s 17.41 / 15.607s
writing 34.06 / 9.686s 34.80 / 9.499s 17.72 / 19.242s 17.81 / 19.456s
multilingual 39.82 / 6.787s 40.46 / 6.688s 21.61 / 13.162s 20.47 / 13.268s
summarization 32.05 / 7.637s 32.55 / 7.521s 16.86 / 11.983s 17.41 / 12.812s
roleplay 31.85 / 16.352s 32.13 / 16.247s 16.50 / 31.989s 17.55 / 30.468s
overall 34.53 / 8.893s 34.92 / 8.814s 17.16 / 18.041s 17.51 / 17.818s

B4500

Cells: avg pred_t/s / avg latency.

category c1 OFF c1 ON c4 OFF c4 ON
coding 77.21 / 5.030s 78.12 / 5.132s 43.59 / 9.658s 41.56 / 9.950s
humanities 83.67 / 4.121s 84.01 / 4.098s 36.58 / 8.938s 35.45 / 9.196s
math 90.15 / 3.235s 90.20 / 3.238s 40.14 / 7.365s 40.63 / 7.315s
qa 69.73 / 3.864s 69.82 / 3.873s 36.98 / 7.805s 32.70 / 7.769s
rag 83.57 / 4.008s 83.66 / 4.022s 33.08 / 8.409s 35.96 / 8.573s
reasoning 87.23 / 3.175s 87.50 / 3.166s 39.35 / 7.640s 36.22 / 7.904s
stem 87.19 / 3.139s 87.39 / 3.129s 38.96 / 7.329s 38.36 / 7.468s
writing 84.46 / 4.630s 84.74 / 4.619s 39.44 / 9.654s 36.30 / 9.760s
multilingual 94.65 / 3.320s 94.66 / 3.316s 42.73 / 6.913s 42.36 / 7.049s
summarization 76.87 / 2.961s 77.11 / 2.872s 36.99 / 6.597s 35.95 / 6.662s
roleplay 73.07 / 8.074s 73.16 / 8.038s 38.38 / 15.239s 39.22 / 14.844s
overall 82.53 / 4.141s 82.76 / 4.137s 38.75 / 8.686s 37.70 / 8.772s

Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,101 @@ static int next_power_of_2(int x) {

#endif // CUB_TOP_K_AVAILABLE


// Two-stage top-k for wide rows: a global top-k element has at most k-1 larger
// elements, so at most k-1 inside its own tile and tiling cannot drop a winner.
#define TOPK_CAND 1024 // argsort_f32_i32_cuda_bitonic's row limit

// measured on H200 and A10G
#define TOPK_BLOCK 256
#define TOPK_TILE_WIDE 8192
#define TOPK_TILE 4096

template <int TILE, int BLOCK>
static __global__ void topk_tile(const float * src, float * cand_val, int * cand_idx,
const int ncols, const int ntiles, const int k) {
__shared__ uint64_t smem[BLOCK];

const int row = blockIdx.x / ntiles;
const int tile = blockIdx.x % ntiles;
const float * row_ptr = src + (size_t) row * ncols;

uint64_t keys[TILE / BLOCK];
#pragma unroll
for (int i = 0; i < TILE / BLOCK; ++i) {
const int col = tile * TILE + threadIdx.x + i * BLOCK;
uint32_t b = col < ncols ? __float_as_uint(row_ptr[col]) : 0;
b = (b & 0x80000000u) ? ~b : (b | 0x80000000u);
keys[i] = col < ncols ? (((uint64_t) b << 32) | (uint32_t) (ncols - 1 - col)) : 0;
}

const size_t out = ((size_t) row * ntiles + tile) * k;
for (int j = 0; j < k; ++j) {
uint64_t local = 0;
#pragma unroll
for (int i = 0; i < TILE / BLOCK; ++i) {
local = max(local, keys[i]);
}
smem[threadIdx.x] = local;
__syncthreads();
for (int s = BLOCK / 2; s > 0; s >>= 1) {
if (threadIdx.x < s) {
smem[threadIdx.x] = max(smem[threadIdx.x], smem[threadIdx.x + s]);
}
__syncthreads();
}
const uint64_t best = smem[0];
if (threadIdx.x == 0) {
const int col = ncols - 1 - (int) (best & 0xFFFFFFFFu);
cand_val[out + j] = best ? row_ptr[col] : -INFINITY;
cand_idx[out + j] = best ? col : 0;
}
#pragma unroll
for (int i = 0; i < TILE / BLOCK; ++i) {
if (keys[i] == best) {
keys[i] = 0;
}
}
__syncthreads();
}
}

// The argsort ranks candidates; turn its positions back into columns.
static __global__ void topk_unmap(const int * cand_idx, const int * order, int * dst,
const int ncand, const int k) {
for (int i = threadIdx.x; i < k; i += blockDim.x) {
dst[(size_t) blockIdx.x * k + i] = cand_idx[(size_t) blockIdx.x * ncand + order[(size_t) blockIdx.x * ncand + i]];
}
}

static bool ggml_cuda_top_k_tiled(ggml_cuda_pool & pool, const float * src, int * dst,
const int ncols, const int nrows, const int k,
cudaStream_t stream) {
// Narrow rows are already handled whole by the bitonic sort below.
const int tile = ncols >= 65536 ? TOPK_TILE_WIDE : TOPK_TILE;
const int ntiles = (ncols + tile - 1) / tile;
const int ncand = ntiles * k;
if (ncols <= TOPK_CAND || ncand > TOPK_CAND) {
return false;
}

ggml_cuda_pool_alloc<float> cand_val(pool, (size_t) nrows * ncand);
ggml_cuda_pool_alloc<int> cand_idx(pool, (size_t) nrows * ncand);
ggml_cuda_pool_alloc<int> order (pool, (size_t) nrows * ncand);

if (tile == TOPK_TILE_WIDE) {
topk_tile<TOPK_TILE_WIDE, TOPK_BLOCK><<<nrows * ntiles, TOPK_BLOCK, 0, stream>>>(
src, cand_val.get(), cand_idx.get(), ncols, ntiles, k);
} else {
topk_tile<TOPK_TILE, TOPK_BLOCK><<<nrows * ntiles, TOPK_BLOCK, 0, stream>>>(
src, cand_val.get(), cand_idx.get(), ncols, ntiles, k);
}
argsort_f32_i32_cuda_bitonic(cand_val.get(), order.get(), ncand, nrows,
GGML_SORT_ORDER_DESC, stream);
topk_unmap<<<nrows, TOPK_BLOCK, 0, stream>>>(cand_idx.get(), order.get(), dst, ncand, k);
return true;
}

void ggml_cuda_op_top_k(ggml_backend_cuda_context & ctx, ggml_tensor * dst) {
const ggml_tensor * src0 = dst->src[0];
const float * src0_d = (const float *) src0->data;
Expand All @@ -63,6 +158,11 @@ void ggml_cuda_op_top_k(ggml_backend_cuda_context & ctx, ggml_tensor * dst) {
const int64_t nrows = ggml_nrows(src0);
const int64_t k = dst->ne[0];
ggml_cuda_pool & pool = ctx.pool();

if (ggml_cuda_top_k_tiled(pool, src0_d, dst_d, ncols, nrows, k, stream)) {
return;
}

#ifdef CUB_TOP_K_AVAILABLE
// TODO: Switch to `DeviceSegmentedTopK` for multi-row TopK once implemented
// https://github.com/NVIDIA/cccl/issues/6391
Expand Down
25 changes: 25 additions & 0 deletions gguf-py/gguf/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,10 @@ class LLM:
TARGET_LAYERS = "{arch}.target_layers"
TARGET_HIDDEN_SIZE = "{arch}.target_hidden_size"
BLOCK_SIZE = "{arch}.block_size"
CONV_KERNEL_SIZE = "{arch}.conv_kernel_size"
CONV_GROUP_SIZE = "{arch}.conv_group_size"
SELECTOR_RANK = "{arch}.selector_rank"
SELECTOR_TOP_K = "{arch}.selector_top_k"
SAMPLE_FROM_ANCHOR = "{arch}.sample_from_anchor"
NORM_BEFORE_RESIDUAL = "{arch}.norm_before_residual"
NORM_BEFORE_FC = "{arch}.norm_before_fc"
Expand Down Expand Up @@ -1133,6 +1137,13 @@ class MODEL_TENSOR(IntEnum):
DSPARK_MARKOV_W1 = auto() # markov head: prev-token embed
DSPARK_MARKOV_W2 = auto() # markov head: bias projection
DSPARK_CONF_PROJ = auto() # confidence head
DFLASH_ATTN_CONV_BASE = auto()
DFLASH_ATTN_CONV_PROJ = auto()
DFLASH_FFN_CONV_BASE = auto()
DFLASH_FFN_CONV_PROJ = auto()
DFLASH_SELECTOR_PREV = auto()
DFLASH_SELECTOR_NEXT = auto()
DFLASH_SELECTOR_HIDDEN = auto()
# lfm2 audio
A_ENC_NORM_CONV = auto()
A_ENC_LINEAR_POS = auto()
Expand Down Expand Up @@ -1875,6 +1886,13 @@ class MODEL_TENSOR(IntEnum):
MODEL_TENSOR.DSPARK_MARKOV_W1: "markov_w1",
MODEL_TENSOR.DSPARK_MARKOV_W2: "markov_w2",
MODEL_TENSOR.DSPARK_CONF_PROJ: "conf_proj",
MODEL_TENSOR.DFLASH_ATTN_CONV_BASE: "blk.{bid}.attn_conv_base",
MODEL_TENSOR.DFLASH_ATTN_CONV_PROJ: "blk.{bid}.attn_conv_proj",
MODEL_TENSOR.DFLASH_FFN_CONV_BASE: "blk.{bid}.ffn_conv_base",
MODEL_TENSOR.DFLASH_FFN_CONV_PROJ: "blk.{bid}.ffn_conv_proj",
MODEL_TENSOR.DFLASH_SELECTOR_PREV: "selector_predecessor",
MODEL_TENSOR.DFLASH_SELECTOR_NEXT: "selector_successor",
MODEL_TENSOR.DFLASH_SELECTOR_HIDDEN: "selector_hidden",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
MODEL_TENSOR.DFLASH_ATTN_CONV_BASE: "blk.{bid}.attn_conv_base",
MODEL_TENSOR.DFLASH_ATTN_CONV_PROJ: "blk.{bid}.attn_conv_proj",
MODEL_TENSOR.DFLASH_FFN_CONV_BASE: "blk.{bid}.ffn_conv_base",
MODEL_TENSOR.DFLASH_FFN_CONV_PROJ: "blk.{bid}.ffn_conv_proj",
MODEL_TENSOR.DFLASH_SELECTOR_PREV: "selector_predecessor",
MODEL_TENSOR.DFLASH_SELECTOR_NEXT: "selector_successor",
MODEL_TENSOR.DFLASH_SELECTOR_HIDDEN: "selector_hidden",
MODEL_TENSOR.DFLASH_ATTN_CONV_BASE: "blk.{bid}.attn_conv_base",
MODEL_TENSOR.DFLASH_ATTN_CONV_PROJ: "blk.{bid}.attn_conv_proj",
MODEL_TENSOR.DFLASH_FFN_CONV_BASE: "blk.{bid}.ffn_conv_base",
MODEL_TENSOR.DFLASH_FFN_CONV_PROJ: "blk.{bid}.ffn_conv_proj",
MODEL_TENSOR.DFLASH_SELECTOR_PREV: "selector_predecessor",
MODEL_TENSOR.DFLASH_SELECTOR_NEXT: "selector_successor",
MODEL_TENSOR.DFLASH_SELECTOR_HIDDEN: "selector_hidden",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 64f765f

MODEL_TENSOR.D2T: "d2t",
}

Expand Down Expand Up @@ -4865,6 +4883,13 @@ class MODEL_TENSOR(IntEnum):
MODEL_TENSOR.DSPARK_MARKOV_W1,
MODEL_TENSOR.DSPARK_MARKOV_W2,
MODEL_TENSOR.DSPARK_CONF_PROJ,
MODEL_TENSOR.DFLASH_ATTN_CONV_BASE,
MODEL_TENSOR.DFLASH_ATTN_CONV_PROJ,
MODEL_TENSOR.DFLASH_FFN_CONV_BASE,
MODEL_TENSOR.DFLASH_FFN_CONV_PROJ,
MODEL_TENSOR.DFLASH_SELECTOR_PREV,
MODEL_TENSOR.DFLASH_SELECTOR_NEXT,
MODEL_TENSOR.DFLASH_SELECTOR_HIDDEN,
],
MODEL_ARCH.MISTRAL4: [
MODEL_TENSOR.TOKEN_EMBD,
Expand Down
12 changes: 12 additions & 0 deletions gguf-py/gguf/gguf_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,18 @@ def add_sliding_window(self, value: int) -> None:
def add_block_size(self, value: int) -> None:
self.add_uint32(Keys.LLM.BLOCK_SIZE.format(arch=self.arch), value)

def add_conv_kernel_size(self, value: int) -> None:
self.add_uint32(Keys.LLM.CONV_KERNEL_SIZE.format(arch=self.arch), value)

def add_conv_group_size(self, value: int) -> None:
self.add_uint32(Keys.LLM.CONV_GROUP_SIZE.format(arch=self.arch), value)

def add_selector_rank(self, value: int) -> None:
self.add_uint32(Keys.LLM.SELECTOR_RANK.format(arch=self.arch), value)

def add_selector_top_k(self, value: int) -> None:
self.add_uint32(Keys.LLM.SELECTOR_TOP_K.format(arch=self.arch), value)

def add_sample_from_anchor(self, value: bool) -> None:
self.add_bool(Keys.LLM.SAMPLE_FROM_ANCHOR.format(arch=self.arch), value)

Expand Down
28 changes: 28 additions & 0 deletions gguf-py/gguf/tensor_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -1353,6 +1353,34 @@ class TensorNameMap:
"model.confidence_head.proj", # dspark
),

MODEL_TENSOR.DFLASH_ATTN_CONV_BASE: (
"model.layers.{bid}.attention_conv.base_kernel",
),

MODEL_TENSOR.DFLASH_ATTN_CONV_PROJ: (
"model.layers.{bid}.attention_conv.kernel_projection",
),

MODEL_TENSOR.DFLASH_FFN_CONV_BASE: (
"model.layers.{bid}.mlp_conv.base_kernel",
),

MODEL_TENSOR.DFLASH_FFN_CONV_PROJ: (
"model.layers.{bid}.mlp_conv.kernel_projection",
),

MODEL_TENSOR.DFLASH_SELECTOR_PREV: (
"model.candidate_selector.predecessor_codebook",
),

MODEL_TENSOR.DFLASH_SELECTOR_NEXT: (
"model.candidate_selector.successor_codebook",
),

MODEL_TENSOR.DFLASH_SELECTOR_HIDDEN: (
"model.candidate_selector.hidden_projection",
),

MODEL_TENSOR.CLS: (
"classifier", # jina
"classifier.dense", # roberta
Expand Down
1 change: 1 addition & 0 deletions include/llama.h
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ extern "C" {
LLAMA_API int32_t llama_model_n_embd_out (const struct llama_model * model);
LLAMA_API int32_t llama_model_n_layer (const struct llama_model * model);
LLAMA_API int32_t llama_model_n_layer_nextn(const struct llama_model * model);
LLAMA_API int32_t llama_model_dflash_selector_top_k(const struct llama_model * model);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Move this to llama-ext.h

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in e91bca5.

LLAMA_API int32_t llama_model_n_head (const struct llama_model * model);
LLAMA_API int32_t llama_model_n_head_kv (const struct llama_model * model);
LLAMA_API int32_t llama_model_n_swa (const struct llama_model * model);
Expand Down
Loading