Team Ai
Datasetpublic

Brunobkr/llama.cpp_AlgMor24_github

ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.

sourceHugging Faceupdated 2mo agoView on Hugging Face
0likes3kdownloads
test-llama-archs.cpp727 linesDownload Raw Back to tests
1#include "common.h"2#include "log.h"3#include "ggml-backend.h"4#include "ggml.h"5#include "gguf.h"6#include "ggml-cpp.h"7#include "llama.h"8#include "llama-cpp.h"9 10// TODO: replace with #include "llama-ext.h" in the future11#include "../src/llama-arch.h"12#include "../src/llama-model-saver.h"13 14#include <cinttypes>15#include <cstddef>16#include <cstdio>17#include <cstring>18#include <cstdint>19#include <random>20#include <stdexcept>21#include <string>22#include <utility>23#include <vector>24 25// normalized mean squared error = mse(a, b) / mse(a, 0)26static double nmse(const std::vector<float> & a, const std::vector<float> & b) {27    GGML_ASSERT(a.size() == b.size());28    double mse_a_b = 0.0;29    double mse_a_0 = 0.0;30 31    for (size_t i = 0; i < a.size(); i++) {32        float a_i = a[i];33        float b_i = b[i];34 35        mse_a_b += (a_i - b_i) * (a_i - b_i);36        mse_a_0 += a_i * a_i;37    }38 39    return mse_a_b / mse_a_0;40}41 42static void set_tensor_data(struct ggml_tensor * tensor, void * userdata) {43    size_t seed = *(const size_t *) userdata;44    std::hash<std::string> hasher;45    seed ^= hasher(tensor->name);46    std::mt19937 gen(seed);47    std::normal_distribution<float> dis(0.0f, 1.0e-2f);48 49    const int64_t ne = ggml_nelements(tensor);50    if (tensor->type == GGML_TYPE_F32) {51        std::vector<float> tmp(ne);52        for (int64_t i = 0; i < ne; i++) {53            tmp[i] = dis(gen);54        }55        ggml_backend_tensor_set(tensor, tmp.data(), 0, ggml_nbytes(tensor));56    } else if (tensor->type == GGML_TYPE_F16) {57        std::vector<ggml_fp16_t> tmp(ne);58        for (int64_t i = 0; i < ne; i++) {59            tmp[i] = ggml_fp32_to_fp16(dis(gen));60        }61        ggml_backend_tensor_set(tensor, tmp.data(), 0, ggml_nbytes(tensor));62    } else {63        GGML_ABORT("fatal error");64    }65}66 67static void usage(char ** argv) {68    printf("Usage: %s [-a/--arch arch] [-s/--seed seed] [-v/--verbose]\n", argv[0]);69}70 71static std::vector<llama_token> get_tokens(const uint32_t n_tokens, const uint32_t n_vocab, const size_t seed){72    std::mt19937 gen(seed);73    std::uniform_int_distribution<> dis(0, n_vocab - 1);74    std::vector<llama_token> ret;75    ret.reserve(n_tokens);76    for (uint32_t i = 0; i < n_tokens; i++) {77        ret.push_back(dis(gen));78    }79    return ret;80}81 82static gguf_context_ptr get_gguf_ctx(const llm_arch arch, const bool moe) {83    gguf_context_ptr ret(gguf_init_empty());84    llama_model_saver ms(arch, ret.get());85    const uint32_t n_ctx = 128;86 87    uint32_t n_vocab = 128;88    uint32_t n_embd  = 256;89    uint32_t n_head  = 2;90    uint32_t n_ff    = 384;91    uint32_t n_layer = 2;92    if (arch == LLM_ARCH_LLAMA4) {93        n_layer = 4; // hparams.n_no_rope_layer_step is hard-coded to 494    } else if (arch == LLM_ARCH_GEMMA4) {95        n_embd = 128;96        n_head = 2;97        n_ff   = 192;98        n_layer = 5; // need at least 5 for swa_pattern (every 5th is full_attention)99    } else if (arch == LLM_ARCH_GEMMA3N) {100        n_embd = 64;101        n_head = 1;102        n_ff   = 96;103        n_layer = 22; // hparams.n_layer_kv_from_start = 20 is hardcoded104    } else if (arch == LLM_ARCH_DEEPSEEK2105            || arch == LLM_ARCH_DEEPSEEK32106            || arch == LLM_ARCH_GLM_DSA107            || arch == LLM_ARCH_KIMI_LINEAR108            || arch == LLM_ARCH_MISTRAL4) {109        n_embd = 128;110        n_head = 1;111        n_ff   = 192;112    } else if (arch == LLM_ARCH_NEMOTRON_H || arch == LLM_ARCH_NEMOTRON_H_MOE) {113        n_layer = 3;114    } else if (arch == LLM_ARCH_CHAMELEON) {115        n_vocab = 10240;116    } else if (arch == LLM_ARCH_QWEN3TTS) {117        n_vocab = 4096; // must be >= the hard-coded codec head size (3072)118    }119 120    const uint32_t n_embd_head = n_embd / n_head;121 122    ms.add_kv(LLM_KV_GENERAL_ARCHITECTURE,      llm_arch_name(arch));123    ms.add_kv(LLM_KV_VOCAB_SIZE,                n_vocab);124    ms.add_kv(LLM_KV_CONTEXT_LENGTH,            n_ctx);125    ms.add_kv(LLM_KV_EMBEDDING_LENGTH,          n_embd);126    ms.add_kv(LLM_KV_FEATURES_LENGTH,           n_embd);127    ms.add_kv(LLM_KV_BLOCK_COUNT,               n_layer);128    ms.add_kv(LLM_KV_LEADING_DENSE_BLOCK_COUNT, uint32_t(1));129 130    if (arch == LLM_ARCH_NEMOTRON_H || arch == LLM_ARCH_NEMOTRON_H_MOE) {131        std::vector<uint32_t> n_ff_per_layer;132        n_ff_per_layer.reserve(n_layer);133        for (uint32_t il = 0; il < n_layer; il++) {134            n_ff_per_layer.push_back(il <= 1 ? 0 : n_ff);135        }136        ms.add_kv(LLM_KV_FEED_FORWARD_LENGTH, n_ff_per_layer);137    } else {138        ms.add_kv(LLM_KV_FEED_FORWARD_LENGTH, n_ff);139    }140 141    ms.add_kv(LLM_KV_USE_PARALLEL_RESIDUAL,   false);142    ms.add_kv(LLM_KV_LOGIT_SCALE,             1.0f);143    ms.add_kv(LLM_KV_TIME_MIX_EXTRA_DIM,      uint32_t(64));144    ms.add_kv(LLM_KV_TIME_DECAY_EXTRA_DIM,    uint32_t(128));145    ms.add_kv(LLM_KV_FULL_ATTENTION_INTERVAL, uint32_t(2));146 147    if (arch == LLM_ARCH_PLAMO2 || arch == LLM_ARCH_JAMBA || arch == LLM_ARCH_NEMOTRON_H || arch == LLM_ARCH_NEMOTRON_H_MOE ||148            arch == LLM_ARCH_GRANITE_HYBRID || arch == LLM_ARCH_LFM2 || arch == LLM_ARCH_LFM2MOE || arch == LLM_ARCH_KIMI_LINEAR) {149        GGML_ASSERT(n_layer >= 2);150        std::vector<uint32_t> n_head_per_layer;151        n_head_per_layer.reserve(n_layer);152        for (uint32_t il = 0; il < n_layer; il++) {153            n_head_per_layer.push_back(il == 1 ? 0 : n_head);154        }155        ms.add_kv(LLM_KV_ATTENTION_HEAD_COUNT, n_head_per_layer);156        ms.add_kv(LLM_KV_ATTENTION_HEAD_COUNT_KV, n_head_per_layer);157    } else {158        ms.add_kv(LLM_KV_ATTENTION_HEAD_COUNT, n_head);159        ms.add_kv(LLM_KV_ATTENTION_HEAD_COUNT_KV, n_head);160    }161 162    ms.add_kv(LLM_KV_ATTENTION_MAX_ALIBI_BIAS, 8.0f);163    if (arch == LLM_ARCH_DEEPSEEK2164            || arch == LLM_ARCH_DEEPSEEK32165            || arch == LLM_ARCH_GLM_DSA166            || arch == LLM_ARCH_KIMI_LINEAR167            || arch == LLM_ARCH_MISTRAL4) {168        ms.add_kv(LLM_KV_ATTENTION_KEY_LENGTH,       uint32_t(576));169        ms.add_kv(LLM_KV_ATTENTION_VALUE_LENGTH,     uint32_t(512));170        ms.add_kv(LLM_KV_ROPE_DIMENSION_COUNT,       uint32_t(64));171        ms.add_kv(LLM_KV_ATTENTION_KEY_LENGTH_MLA,   uint32_t(192));172        ms.add_kv(LLM_KV_ATTENTION_VALUE_LENGTH_MLA, uint32_t(128));173    } else if (arch == LLM_ARCH_MINIMAX_M3) {174        // partial rotary: n_rot must not exceed the indexer key length (64)175        ms.add_kv(LLM_KV_ROPE_DIMENSION_COUNT,       uint32_t(64));176    }177    ms.add_kv(LLM_KV_ATTENTION_CLAMP_KQV,              1.0f);178    ms.add_kv(LLM_KV_ATTENTION_LAYERNORM_EPS,          1e-5f);179    ms.add_kv(LLM_KV_ATTENTION_LAYERNORM_RMS_EPS,      1e-5f);180    ms.add_kv(LLM_KV_ATTENTION_GROUPNORM_EPS,          1e-5f);181    ms.add_kv(LLM_KV_ATTENTION_GROUPNORM_GROUPS,       uint32_t(8));182    ms.add_kv(LLM_KV_ATTENTION_Q_LORA_RANK,            uint32_t(512));183    ms.add_kv(LLM_KV_ATTENTION_KV_LORA_RANK,           uint32_t(512));184    ms.add_kv(LLM_KV_ATTENTION_RELATIVE_BUCKETS_COUNT, uint32_t(8));185    ms.add_kv(LLM_KV_ATTENTION_SLIDING_WINDOW,         n_ctx/8);186 187    if (arch == LLM_ARCH_GEMMA4) {188        ms.add_kv(LLM_KV_EMBEDDING_LENGTH_PER_LAYER,      n_embd/2);189        ms.add_kv(LLM_KV_ATTENTION_SHARED_KV_LAYERS,      uint32_t(0));190        ms.add_kv(LLM_KV_ATTENTION_KEY_LENGTH_SWA,        n_embd_head);191        ms.add_kv(LLM_KV_ATTENTION_VALUE_LENGTH_SWA,      n_embd_head);192        ms.add_kv(LLM_KV_ROPE_FREQ_BASE_SWA,              10000.0f);193        // SWA pattern: every 5th layer is full attention (matches E2B layer_types)194        ms.add_kv(LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN, uint32_t(5));195    } else if (arch == LLM_ARCH_COHERE2MOE || arch == LLM_ARCH_MIMO2 || arch == LLM_ARCH_STEP35 || arch == LLM_ARCH_MUSE_GLIMMER) {196        std::vector<uint32_t> pattern;197        pattern.reserve(n_layer);198        for (uint32_t il = 0; il < n_layer; il++) {199            pattern.push_back(il % 2);200        }201        ms.add_kv(LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN, pattern);202    } else {203        ms.add_kv(LLM_KV_ATTENTION_SLIDING_WINDOW_PATTERN, uint32_t(2));204    }205 206    // MSA requires one indexer head per GQA (KV) head, unlike the DSA archs where the207    // indexer head count is independent of the main attention head count.208    ms.add_kv(LLM_KV_ATTENTION_INDEXER_HEAD_COUNT,   arch == LLM_ARCH_MINIMAX_M3 ? n_head : uint32_t(1));209    ms.add_kv(LLM_KV_ATTENTION_INDEXER_KEY_LENGTH,   uint32_t(64));210    ms.add_kv(LLM_KV_ATTENTION_INDEXER_TOP_K,        uint32_t(8));211    ms.add_kv(LLM_KV_ATTENTION_INDEXER_BLOCK_SIZE,   uint32_t(4));212    ms.add_kv(LLM_KV_ATTENTION_INDEXER_LOCAL_BLOCKS, uint32_t(1));213    ms.add_kv(LLM_KV_ROPE_DIMENSION_SECTIONS, std::vector<uint32_t>({n_embd_head/4, n_embd_head/4, n_embd_head/4, n_embd_head/4}));214    ms.add_kv(LLM_KV_TOKENIZER_MODEL,         "no_vocab");215    // ms.add_kv(LLM_KV_DENSE_2_FEAT_OUT,     n_embd);216    // ms.add_kv(LLM_KV_DENSE_3_FEAT_IN,      n_embd);217 218    if (moe) {219        ms.add_kv(LLM_KV_EXPERT_FEED_FORWARD_LENGTH, n_ff);220        ms.add_kv(LLM_KV_EXPERT_SHARED_FEED_FORWARD_LENGTH, n_ff / 2);  // distinct from n_ff so a saver key-clobber surfaces on reload221        ms.add_kv(LLM_KV_INTERLEAVE_MOE_LAYER_STEP,  uint32_t(2));222        ms.add_kv(LLM_KV_EXPERT_COUNT,               uint32_t(2));223        ms.add_kv(LLM_KV_EXPERT_USED_COUNT,          uint32_t(1));224        ms.add_kv(LLM_KV_EXPERT_SHARED_COUNT,        uint32_t(1));225        ms.add_kv(LLM_KV_EXPERT_GATING_FUNC,         uint32_t(2)); // sigmoid226        ms.add_kv(LLM_KV_EXPERT_GROUP_SCALE,         1.0f);227        ms.add_kv(LLM_KV_EXPERTS_PER_GROUP,          uint32_t(1));228    }229 230    ms.add_kv(LLM_KV_POSNET_EMBEDDING_LENGTH,   n_embd);231    ms.add_kv(LLM_KV_POSNET_BLOCK_COUNT,        n_layer);232    ms.add_kv(LLM_KV_CONVNEXT_EMBEDDING_LENGTH, n_embd);233    ms.add_kv(LLM_KV_CONVNEXT_BLOCK_COUNT,      n_layer);234    ms.add_kv(LLM_KV_XIELU_ALPHA_N,             1.0f);235    ms.add_kv(LLM_KV_XIELU_ALPHA_P,             1.0f);236    ms.add_kv(LLM_KV_XIELU_BETA,                1.0f);237    ms.add_kv(LLM_KV_XIELU_EPS,                 1.0e-7f);238    ms.add_kv(LLM_KV_SSM_INNER_SIZE,            arch == LLM_ARCH_QWEN3NEXT || arch == LLM_ARCH_QWEN35 || arch == LLM_ARCH_QWEN35MOE ? 256 : 2*n_embd);239    ms.add_kv(LLM_KV_SSM_CONV_KERNEL,           uint32_t(4));240    ms.add_kv(LLM_KV_SSM_STATE_SIZE,            uint32_t(128));241    ms.add_kv(LLM_KV_SSM_TIME_STEP_RANK,        n_head);242    ms.add_kv(LLM_KV_SSM_GROUP_COUNT,           arch == LLM_ARCH_PLAMO2 ? 0 : uint32_t(2));243    ms.add_kv(LLM_KV_KDA_HEAD_DIM,              uint32_t(128));244    ms.add_kv(LLM_KV_WKV_HEAD_SIZE,             n_embd/n_head);245    ms.add_kv(LLM_KV_SHORTCONV_L_CACHE,         uint32_t(3));246 247    for (uint32_t il = 0; il < n_layer; il++) {248        ggml_tensor t;249        memset(&t, 0, sizeof(ggml_tensor));250        t.type = GGML_TYPE_F16;251        ggml_format_name(&t, "conv%" PRIu32 "d.weight", il);252        gguf_add_tensor(ms.gguf_ctx, &t);253        ggml_format_name(&t, "posnet.%" PRIu32 ".conv1.weight", il);254        gguf_add_tensor(ms.gguf_ctx, &t);255        ggml_format_name(&t, "posnet.%" PRIu32 ".conv2.weight", il);256        gguf_add_tensor(ms.gguf_ctx, &t);257        ggml_format_name(&t, "convnext.%" PRIu32 ".dw.weight", il);258        gguf_add_tensor(ms.gguf_ctx, &t);259    }260    return ret;261}262 263static bool silent_model_load_progress(float /*progress*/, void * /*user_data*/) {264    return true;265}266 267static std::pair<llama_model_ptr, llama_context_ptr> get_model_and_ctx(268        struct gguf_context * gguf_ctx, FILE * file, const size_t seed, const std::vector<ggml_backend_dev_t> & devs,269        const llama_split_mode split_mode = LLAMA_SPLIT_MODE_LAYER, bool encode = false) {270    GGML_ASSERT((gguf_ctx == nullptr) != (file == nullptr));271    llama_model_params model_params = llama_model_default_params();272    model_params.progress_callback = silent_model_load_progress;273    std::vector<ggml_backend_dev_t> devs_copy = devs;274    devs_copy.push_back(nullptr);275    model_params.devices = devs_copy.data();276    model_params.split_mode = split_mode;277 278    llama_context_params ctx_params = llama_context_default_params();279    ctx_params.n_ctx = 0;280    ctx_params.n_threads = 4;281    ctx_params.n_threads_batch = 4;282    if (!encode) {283        ctx_params.n_ubatch = 64;284    }285 286    size_t tmp = seed;287    llama_model_ptr model(gguf_ctx != nullptr ?288        llama_model_init_from_user(gguf_ctx, set_tensor_data, &tmp, model_params) :289        llama_model_load_from_file_ptr(file, model_params));290    if (!model) {291        throw std::runtime_error("failed to create llama model");292    }293    llama_context_ptr lctx(llama_init_from_model(model.get(), ctx_params));294    if (!lctx) {295        throw std::runtime_error("failed to create llama context");296    }297    return std::make_pair(std::move(model), std::move(lctx));298}299 300static std::vector<float> get_logits(301        llama_model * model, llama_context * lctx, const std::vector<llama_token> & tokens, bool encode = false) {302    const uint32_t n_vocab  = llama_vocab_n_tokens(llama_model_get_vocab(model));303    const uint32_t n_ctx    = llama_n_ctx(lctx);304    const uint32_t n_tokens = tokens.size();305    llama_batch batch = llama_batch_init(n_ctx, 0, 1);306    GGML_ASSERT(n_tokens <= n_ctx);307    for (uint32_t pos = 0; pos < n_tokens; pos++) {308        common_batch_add(batch, tokens[pos], pos, {0}, true);309    }310    batch.n_tokens = n_tokens;311    if (encode) {312        if (llama_encode(lctx, batch)) {313            llama_batch_free(batch);314            throw std::runtime_error("failed to encode batch");315        }316    }317    if (llama_decode(lctx, batch)) {318        llama_batch_free(batch);319        throw std::runtime_error("failed to decode batch");320    }321 322    std::vector<float> ret;323    ret.reserve(n_tokens*n_vocab);324    for (uint32_t i = 0; i < n_tokens; i++) {325        const float * logits_ith = llama_get_logits_ith(lctx, i);326        for (uint32_t j = 0; j < n_vocab; j++) {327            ret.push_back(logits_ith[j]);328        }329    }330    llama_batch_free(batch);331    return ret;332}333 334static bool moe_mandatory(const llm_arch arch) {335    switch (arch) {336        case LLM_ARCH_LLAMA4:337        case LLM_ARCH_COHERE2MOE:338        case LLM_ARCH_GROK:339        case LLM_ARCH_QWEN2MOE:340        case LLM_ARCH_QWEN3MOE:341        case LLM_ARCH_QWEN3NEXT:342        case LLM_ARCH_QWEN3VLMOE:343        case LLM_ARCH_QWEN35MOE:344        case LLM_ARCH_PHIMOE:345        case LLM_ARCH_DBRX:346        case LLM_ARCH_OLMOE:347        case LLM_ARCH_ARCTIC:348        case LLM_ARCH_DEEPSEEK:349        case LLM_ARCH_DEEPSEEK2:350        case LLM_ARCH_DEEPSEEK32:351        case LLM_ARCH_GLM4_MOE:352        case LLM_ARCH_GLM_DSA:353        case LLM_ARCH_EXAONE_MOE:354        case LLM_ARCH_BAILINGMOE:355        case LLM_ARCH_BAILINGMOE2:356        case LLM_ARCH_DOTS1:357        case LLM_ARCH_AFMOE:358        case LLM_ARCH_ERNIE4_5:359        case LLM_ARCH_ERNIE4_5_MOE:360        case LLM_ARCH_HUNYUAN_MOE:361        case LLM_ARCH_HY_V3:362        case LLM_ARCH_OPENAI_MOE:363        case LLM_ARCH_LFM2MOE:364        case LLM_ARCH_SMALLTHINKER:365        case LLM_ARCH_LLADA_MOE:366        case LLM_ARCH_GROVEMOE:367        case LLM_ARCH_MINIMAX_M2:368        case LLM_ARCH_MINIMAX_M3:369        case LLM_ARCH_RND1:370        case LLM_ARCH_PADDLEOCR:371        case LLM_ARCH_MIMO2:372        case LLM_ARCH_KIMI_LINEAR:373        case LLM_ARCH_STEP35:374        case LLM_ARCH_MISTRAL4:375        case LLM_ARCH_MELLUM:376        case LLM_ARCH_LAGUNA:377            return true;378        default:379            return false;380    }381}382 383static bool moe_implemented(const llm_arch arch) {384    if (moe_mandatory(arch)) {385        return true;386    }387    switch (arch) {388        case LLM_ARCH_LLAMA:389        case LLM_ARCH_REFACT:390        case LLM_ARCH_MINICPM:391        case LLM_ARCH_GRANITE:392        case LLM_ARCH_GRANITE_MOE:393        case LLM_ARCH_MISTRAL3:394        case LLM_ARCH_LLAMA_EMBED:395            return true;396        default:397            return false;398    }399}400 401static bool arch_supported(const llm_arch arch) {402    if (arch == LLM_ARCH_CLIP || arch == LLM_ARCH_GPTJ || arch == LLM_ARCH_UNKNOWN) {403        return false; // These models don't have usable implementations.404    }405    if (arch == LLM_ARCH_CHAMELEON) {406        return false; // Only half-implemented and to be removed in the future.407    }408    if (arch == LLM_ARCH_WAVTOKENIZER_DEC) {409        return false; // FIXME CUDA backend crashes.410    }411    if (arch == LLM_ARCH_GEMMA4 || arch == LLM_ARCH_GEMMA4_ASSISTANT) {412        return false; // FIXME @ngxson413    }414    if (arch == LLM_ARCH_GRANITE_SWITCH) {415        return false; // FIXME adapter fixture416    }417    if (arch == LLM_ARCH_LLAMA_EMBED || arch == LLM_ARCH_GEMMA_EMBEDDING || arch == LLM_ARCH_T5ENCODER) {418        return false; // FIXME Embedding (?) models produce inconsistent results.419    }420    if (arch == LLM_ARCH_RWKV6 || arch == LLM_ARCH_RWKV6QWEN2 || arch == LLM_ARCH_RWKV7 || arch == LLM_ARCH_ARWKV7) {421        return false; // FIXME RWKV models hang indefinitely.422    }423    if (arch == LLM_ARCH_BERT || arch == LLM_ARCH_MODERN_BERT || arch == LLM_ARCH_NOMIC_BERT || arch == LLM_ARCH_NOMIC_BERT_MOE ||424            arch == LLM_ARCH_NEO_BERT || arch == LLM_ARCH_JINA_BERT_V2 || arch == LLM_ARCH_JINA_BERT_V3 || arch == LLM_ARCH_EUROBERT) {425        return false; // TODO vocab426    }427    if (arch == LLM_ARCH_PLM) {428        return false; // TODO tensor shapes429    }430    if (arch == LLM_ARCH_DEEPSEEK2OCR) {431        return false;432    }433    if (arch == LLM_ARCH_DEEPSEEK4) {434        return false;435    }436 437    // FIXME: these hit scheduler/view-backed-output issues with WebGPU on CI.438#ifdef GGML_USE_WEBGPU439    if (arch == LLM_ARCH_DEEPSEEK32 || arch == LLM_ARCH_GLM_DSA) {440        return false;441    }442#endif // GGML_USE_WEBGPU443 444    // FIXME: jamba produces incorrect output (~0.55 NMSE vs CPU) on the HIP445    // backend on RDNA3.5 (gfx1151); the SSM kernels need investigation.446#ifdef GGML_USE_HIP447    if (arch == LLM_ARCH_JAMBA) {448        return false;449    }450#endif // GGML_USE_HIP451 452    return true;453}454 455static int save_models(const llm_arch target_arch, const size_t seed, const ggml_log_level log_level, const std::string & dir) {456    struct user_data_t {457        struct {458            ggml_log_callback callback;459            void * user_data;460        } original_logger;461        ggml_log_level min_level; // prints below this log level go to debug log462    };463    user_data_t ud;464    llama_log_get(&ud.original_logger.callback, &ud.original_logger.user_data);465    ud.min_level = log_level;466 467    llama_log_set([](ggml_log_level level, const char * text, void * user_data) {468        const user_data_t * ud = (const user_data_t *) user_data;469        const ggml_log_level level_eff = level >= ud->min_level ? level : GGML_LOG_LEVEL_DEBUG;470        ud->original_logger.callback(level_eff, text, ud->original_logger.user_data);471    }, &ud);472 473    for (const llm_arch & arch : llm_arch_all()) {474        if (arch == LLM_ARCH_UNKNOWN) {475            continue;476        }477        if (target_arch != LLM_ARCH_UNKNOWN && arch != target_arch) {478            continue;479        }480        if (arch == LLM_ARCH_GEMMA4 || arch == LLM_ARCH_GEMMA4_ASSISTANT) {481            continue; // FIXME: ISWA KV cache initialization needs more fixture params482        }483        if (arch == LLM_ARCH_EAGLE3 || arch == LLM_ARCH_DFLASH) {484            continue;485        }486        for (bool moe : {false, true}) {487            if (moe && !moe_implemented(arch)) {488                continue;489            }490            if (!moe && moe_mandatory(arch)) {491                continue;492            }493            if (!llama_model_saver_supports_arch(arch) || !arch_supported(arch)) {494                LOG_INF("%s: %s model (%s) is unsupported, skipping\n", __func__, llm_arch_name(arch), moe ? "MoE" : "dense");495                continue;496            }497            gguf_context_ptr gguf_ctx = get_gguf_ctx(arch, moe);498            auto model_and_ctx = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, {});499            const std::string path = dir + "/" + llm_arch_name(arch) + (moe ? "-moe.gguf" : "-dense.gguf");500            LOG_INF("%s: Saving %s model (%s) to %s...\n", __func__, llm_arch_name(arch), moe ? "MoE" : "dense", path.c_str());501            llama_model_save_to_file(model_and_ctx.first.get(), path.c_str());502        }503    }504    llama_log_set(ud.original_logger.callback, ud.original_logger.user_data);505    return 0;506}507 508static int test_backends(const llm_arch target_arch, const size_t seed, const ggml_log_level log_level) {509    struct user_data_t {510        struct {511            ggml_log_callback callback;512            void * user_data;513        } original_logger;514        ggml_log_level min_level; // prints below this log level go to debug log515    };516    user_data_t ud;517    llama_log_get(&ud.original_logger.callback, &ud.original_logger.user_data);518    ud.min_level = log_level;519 520    llama_log_set([](ggml_log_level level, const char * text, void * user_data) {521        const user_data_t * ud = (const user_data_t *) user_data;522        const ggml_log_level level_eff = level >= ud->min_level ? level : GGML_LOG_LEVEL_DEBUG;523        ud->original_logger.callback(level_eff, text, ud->original_logger.user_data);524    }, &ud);525 526    const std::vector<llama_token> tokens = get_tokens(128, 128, seed);527 528    struct device_config {529        std::vector<ggml_backend_dev_t> devs;530        std::string                     label;531        llama_split_mode                split_mode;532 533        device_config(std::vector<ggml_backend_dev_t> devs, std::string name, llama_split_mode split_mode)534            : devs(std::move(devs)), label(std::move(name)), split_mode(split_mode) {}535    };536 537    std::vector<device_config> dev_configs;538    size_t max_device_label_length = 4;539    {540        std::vector<ggml_backend_dev_t> devices_meta;541        {542            const size_t device_count = ggml_backend_dev_count();543            for (size_t i = 0; i < device_count; i++) {544                ggml_backend_dev_t dev = ggml_backend_dev_get(i);545                dev_configs.emplace_back(std::vector<ggml_backend_dev_t>{dev}, ggml_backend_dev_description(dev), LLAMA_SPLIT_MODE_LAYER);546                max_device_label_length = std::max(max_device_label_length, dev_configs.back().label.length());547 548                // cpu-based devices cannot be used in tensor split mode549                if (ggml_backend_dev_buffer_type(dev) != ggml_backend_cpu_buffer_type()) {550                    devices_meta.push_back(dev);551                }552            }553        }554 555        dev_configs.emplace_back(devices_meta, "Meta", LLAMA_SPLIT_MODE_TENSOR);556    }557 558    size_t max_arch_name_length = 0;559    for (const llm_arch & arch : llm_arch_all()) {560        max_arch_name_length = std::max(max_arch_name_length, strlen(llm_arch_name(arch)));561    }562 563    const std::string template_header  = std::string("|%" + std::to_string(max_arch_name_length) + "s|%") + std::to_string(max_device_label_length) + "s|%6s|%15s|%9s|\n";564    const std::string template_row_cfg = std::string("|%" + std::to_string(max_arch_name_length) + "s|%") + std::to_string(max_device_label_length) + "s|%6s|";565    const std::string template_row_res = "%15s %10s|%20s|\n";566 567    bool all_ok = true;568    common_log_flush(common_log_main());569    printf(template_header.c_str(), "Model arch.", "Device", "Config", "NMSE vs. CPU", "Roundtrip");570    printf("|");571    for (size_t i = 0; i < max_arch_name_length; i++) {572        printf("-");573    }574    printf("|");575    for (size_t i = 0; i < max_device_label_length; i++) {576        printf("-");577    }578    printf("|------|---------------|---------|\n");579    for (const llm_arch & arch : llm_arch_all()) {580        if (arch == LLM_ARCH_UNKNOWN) {581            continue;582        }583        if (target_arch != LLM_ARCH_UNKNOWN && arch != target_arch) {584            continue;585        }586        if (arch == LLM_ARCH_GEMMA4 || arch == LLM_ARCH_GEMMA4_ASSISTANT) {587            continue; // FIXME: ISWA KV cache initialization needs more fixture params588        }589        if (arch == LLM_ARCH_EAGLE3 || arch == LLM_ARCH_DFLASH) {590            continue;591        }592 593        const bool encode = arch == LLM_ARCH_T5 || arch == LLM_ARCH_DREAM || arch == LLM_ARCH_LLADA || arch == LLM_ARCH_LLADA_MOE || arch == LLM_ARCH_RND1;594        for (bool moe : {false, true}) {595            if (moe && !moe_implemented(arch)) {596                continue;597            }598            if (!moe && moe_mandatory(arch)) {599                continue;600            }601            const std::string config_name = moe ? "MoE" : "Dense";602            gguf_context_ptr gguf_ctx = get_gguf_ctx(arch, moe);603            std::pair<llama_model_ptr, llama_context_ptr> model_and_ctx_cpu;604            std::vector<float> logits_cpu;605            for (device_config & dc : dev_configs) {606                // print test config first; should anything fail during model loading or inference, at least we know which test case caused it607                printf(template_row_cfg.c_str(),608                    llm_arch_name(arch), dc.label.c_str(), config_name.c_str());609                fflush(stdout);610 611                std::pair<llama_model_ptr, llama_context_ptr> model_and_ctx_dev;612                std::vector<float> logits_dev;613                std::string status_nmse      = "\033[1;33mSKIP\033[0m";614                std::string status_roundtrip = "\033[1;33mSKIP\033[0m";615                char nmse_str[12] = {0};616                bool skip = !arch_supported(arch) || (dc.split_mode == LLAMA_SPLIT_MODE_TENSOR && dc.devs.empty());617                if (!skip) {618                    if (logits_cpu.empty()) {619                        model_and_ctx_cpu = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, {}, LLAMA_SPLIT_MODE_LAYER, encode);620                        logits_cpu = get_logits(model_and_ctx_cpu.first.get(), model_and_ctx_cpu.second.get(), tokens, encode);621                    }622                    if (dc.split_mode != LLAMA_SPLIT_MODE_TENSOR || llm_arch_supports_sm_tensor(arch)) {623                        model_and_ctx_dev = get_model_and_ctx(gguf_ctx.get(), nullptr, seed, dc.devs, dc.split_mode, encode);624                        logits_dev = get_logits(model_and_ctx_dev.first.get(), model_and_ctx_dev.second.get(), tokens, encode);625                        const double nmse_val = nmse(logits_cpu, logits_dev);626                        snprintf(nmse_str, sizeof(nmse_str), "(%.2e)", nmse_val);627                        status_nmse = "\033[1;32mOK\033[0m";628                        if (nmse_val > 1e-4) {629                            all_ok = false;630                            status_nmse = "\033[1;31mFAIL\033[0m";631                        }632                    }633 634                    FILE * file = tmpfile(); // Can be null on Windows without administrator privileges.635                    // FIXME: when adding a tensor to a gguf_context a copy is made, this changes the pointer which the meta backend636                    //     in turn uses to map the tensors to their simple equivalents - this is fundamentally incompatible637                    if (file != nullptr && llama_model_saver_supports_arch(arch) && dc.split_mode != LLAMA_SPLIT_MODE_TENSOR) {638                        GGML_ASSERT(model_and_ctx_dev.first && model_and_ctx_dev.second);639                        llama_model_saver ms = llama_model_saver(model_and_ctx_dev.first.get());640                        ms.add_kv_from_model();641                        ms.add_tensors_from_model();642                        ms.save(file);643                        rewind(file);644 645                        auto model_and_ctx_roundtrip = get_model_and_ctx(nullptr, file, seed, dc.devs, dc.split_mode, encode);646                        const std::vector<float> logits_roundtrip = get_logits(647                            model_and_ctx_roundtrip.first.get(), model_and_ctx_roundtrip.second.get(), tokens, encode);648                        status_roundtrip = "\033[1;32mOK\033[0m";649                        GGML_ASSERT(logits_roundtrip.size() == logits_dev.size());650                        for (size_t i = 0; i < logits_roundtrip.size(); i++) {651                            if (logits_roundtrip[i] != logits_dev[i]) {652                                all_ok = false;653                                status_roundtrip = "\033[1;31mFAIL\033[0m";654                                break;655                            }656                        }657                    }658                }659 660                // log the results for this test case661                printf(template_row_res.c_str(),662                    status_nmse.c_str(), nmse_str, status_roundtrip.c_str());663            }664        }665    }666    llama_log_set(ud.original_logger.callback, ud.original_logger.user_data);667    return all_ok ? 0 : 1;668}669 670int main(int argc, char ** argv) {671    // FIXME these tests are disabled in the CI for macOS-latest-cmake-arm64 because they are segfaulting672    common_init();673    std::random_device rd;674 675    llm_arch arch = LLM_ARCH_UNKNOWN;676    size_t seed = rd();677    ggml_log_level log_level = GGML_LOG_LEVEL_ERROR;678    std::string out;679 680    for (int i = 1; i < argc; i++) {681        if (strcmp(argv[i], "-a") == 0 || strcmp(argv[i], "--arch") == 0) {682            if (i + 1 < argc) {683                const std::string arch_name = argv[++i];684                arch = llm_arch_from_string(arch_name);685                if (arch == LLM_ARCH_UNKNOWN) {686                    LOG_ERR("%s: unkown LLM architecture: %s\n", __func__, arch_name.c_str());687                    return 1;688                }689            } else {690                usage(argv);691                return 1;692            }693        }694        if (strcmp(argv[i], "-s") == 0 || strcmp(argv[i], "--seed") == 0) {695            if (i + 1 < argc) {696                seed = std::stoull(argv[++i]);697            } else {698                usage(argv);699                return 1;700            }701        }702        if (strcmp(argv[i], "-v") == 0 || strcmp(argv[i], "--verbose") == 0) {703            log_level = GGML_LOG_LEVEL_INFO;704            continue;705        }706        if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--out") == 0) {707            if (i + 1 < argc) {708                out = argv[++i];709            } else {710                usage(argv);711                return 1;712            }713        }714    }715    printf("%s: using seed %zu\n", __func__, seed);716 717    try {718        if (!out.empty()) {719            return save_models(arch, seed, log_level, out);720        }721        return test_backends(arch, seed, log_level);722    } catch (const std::exception & err) {723        fprintf(stderr, "encountered runtime error: %s\n", err.what());724        return -1;725    }726}727 
Brunobkr/llama.cpp_AlgMor24_github · Team Ai