mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-08-26 15:16:23 +02:00
test: add duplicated index case for ggml_mul_mat_id
This commit is contained in:
@@ -4404,7 +4404,7 @@ struct test_mul_mat_hadamard : public test_mul_mat {
|
||||
}
|
||||
};
|
||||
|
||||
static void init_mul_mat_id_tensors(ggml_context * ctx, int n_mats) {
|
||||
static void init_mul_mat_id_tensors(ggml_context * ctx, int n_mats, bool dup_ids = false) {
|
||||
std::random_device rd;
|
||||
std::default_random_engine rng(rd());
|
||||
for (ggml_tensor * t = ggml_get_first_tensor(ctx); t != NULL; t = ggml_get_next_tensor(ctx, t)) {
|
||||
@@ -4417,6 +4417,12 @@ static void init_mul_mat_id_tensors(ggml_context * ctx, int n_mats) {
|
||||
data[i] = i % n_mats;
|
||||
}
|
||||
std::shuffle(data.begin(), data.end(), rng);
|
||||
if (dup_ids && t->ne[0] >= 2) {
|
||||
// some models (e.g. expert-pruned MoE checkpoints) can end up with a
|
||||
// routing table that selects the same expert twice for one token,
|
||||
// make sure this is handled correctly (see issue #26588)
|
||||
data[1] = data[0];
|
||||
}
|
||||
ggml_backend_tensor_set(t, data.data(), r * t->nb[1], t->ne[0] * sizeof(int32_t));
|
||||
}
|
||||
} else {
|
||||
@@ -4435,9 +4441,10 @@ struct test_mul_mat_id : public test_case {
|
||||
const int64_t m;
|
||||
const int64_t n;
|
||||
const int64_t k;
|
||||
const bool dup_ids; // force a duplicated expert id within a token's selected experts
|
||||
|
||||
std::string vars() override {
|
||||
return VARS_TO_STR8(type_a, type_b, n_mats, n_used, b, m, n, k);
|
||||
return VARS_TO_STR9(type_a, type_b, n_mats, n_used, b, m, n, k, dup_ids);
|
||||
}
|
||||
|
||||
double max_nmse_err() override {
|
||||
@@ -4459,10 +4466,11 @@ struct test_mul_mat_id : public test_case {
|
||||
|
||||
test_mul_mat_id(ggml_type type_a = GGML_TYPE_F32, ggml_type type_b = GGML_TYPE_F32,
|
||||
int n_mats = 8, int n_used = 2, bool b = false,
|
||||
int64_t m = 32, int64_t n = 32, int64_t k = 32)
|
||||
int64_t m = 32, int64_t n = 32, int64_t k = 32, bool dup_ids = false)
|
||||
: type_a(type_a), type_b(type_b), n_mats(n_mats), n_used(n_used), b(b),
|
||||
m(m), n(n), k(k) {
|
||||
m(m), n(n), k(k), dup_ids(dup_ids) {
|
||||
GGML_ASSERT(n_used <= n_mats);
|
||||
GGML_ASSERT(!dup_ids || n_used >= 2);
|
||||
}
|
||||
|
||||
ggml_tensor * build_graph(ggml_context * ctx) override {
|
||||
@@ -4487,7 +4495,7 @@ struct test_mul_mat_id : public test_case {
|
||||
}
|
||||
|
||||
void initialize_tensors(ggml_context * ctx) override {
|
||||
init_mul_mat_id_tensors(ctx, n_mats);
|
||||
init_mul_mat_id_tensors(ctx, n_mats, dup_ids);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9029,7 +9037,16 @@ static std::vector<std::unique_ptr<test_case>> make_test_cases_eval() {
|
||||
test_cases.emplace_back(new test_mul_mat_id(GGML_TYPE_MXFP4, GGML_TYPE_F32, 32, 2, false, 2880, 32, 2880));
|
||||
test_cases.emplace_back(new test_mul_mat_id(GGML_TYPE_Q4_0, GGML_TYPE_F32, 32, 2, false, 2880, 32, 2880));
|
||||
|
||||
// a malformed routing table can select the same expert twice for one token (see issue #26588),
|
||||
// make sure quantized MMQ-style paths do not assume unique expert ids per token
|
||||
for (ggml_type type_a : {GGML_TYPE_F16, GGML_TYPE_Q4_0, GGML_TYPE_Q8_0, GGML_TYPE_MXFP4}) {
|
||||
test_cases.emplace_back(new test_mul_mat_id(type_a, GGML_TYPE_F32, 8, 6, false, 128, 1, 256, true));
|
||||
test_cases.emplace_back(new test_mul_mat_id(type_a, GGML_TYPE_F32, 8, 6, false, 128, 32, 256, true));
|
||||
test_cases.emplace_back(new test_mul_mat_id(type_a, GGML_TYPE_F32, 32, 2, false, 2880, 32, 2880, true));
|
||||
}
|
||||
|
||||
for (ggml_type type_a : all_types) {
|
||||
|
||||
test_cases.emplace_back(new test_mul_mat_id(type_a, GGML_TYPE_F32, 4, 2, false, 64, 16, 3*ggml_blck_size(type_a)));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user