Team Ai
Datasetpublic

echodict/llama.cpp

version https://git-lfs.github.com/spec/v1 oid sha256:cfc44b7ba25614df70e6b65e3341cae0310163bd32fd31a6b928a542df433faf size 30786

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes610downloads
llama.cpp559 linesDownload Raw Back to src
1#include "llama.h"2 3#include "llama-impl.h"4 5#include "llama-chat.h"6#include "llama-context.h"7#include "llama-mmap.h"8#include "llama-vocab.h"9#include "llama-model-loader.h"10#include "llama-model-saver.h"11#include "llama-model.h"12 13#include "ggml.h"14#include "ggml-cpp.h"15#include "ggml-backend.h"16#include "gguf.h"17 18#include <algorithm>19#include <cassert>20#include <cinttypes>21#include <cstddef>22#include <cstdint>23#include <cstdio>24#include <cstring>25#include <ctime>26#include <stdexcept>27#include <vector>28 29#if defined(_MSC_VER)30#pragma warning(disable: 4244 4267) // possible loss of data31#endif32 33//34// interface implementation35//36 37const char * llama_flash_attn_type_name(enum llama_flash_attn_type flash_attn_type) {38    switch (flash_attn_type) {39        case LLAMA_FLASH_ATTN_TYPE_AUTO:40            return "auto";41        case LLAMA_FLASH_ATTN_TYPE_DISABLED:42            return "disabled";43        case LLAMA_FLASH_ATTN_TYPE_ENABLED:44            return "enabled";45    }46    GGML_ABORT("fatal error");47}48 49struct llama_sampler_chain_params llama_sampler_chain_default_params() {50    struct llama_sampler_chain_params result = {51        /*.no_perf =*/ true,52    };53 54    return result;55}56 57size_t llama_max_devices(void) {58    return 16;59}60 61size_t llama_max_tensor_buft_overrides() {62    return 4096;63}64 65bool llama_supports_mmap(void) {66    return llama_mmap::SUPPORTED;67}68 69bool llama_supports_mlock(void) {70    return llama_mlock::SUPPORTED;71}72 73bool llama_supports_gpu_offload(void) {74    return ggml_backend_dev_by_type(GGML_BACKEND_DEVICE_TYPE_GPU) != nullptr ||75           ggml_backend_dev_by_type(GGML_BACKEND_DEVICE_TYPE_IGPU) != nullptr ||76           llama_supports_rpc();77}78 79bool llama_supports_rpc(void) {80    return ggml_backend_reg_by_name("RPC") != nullptr;81}82 83void llama_backend_init(void) {84    ggml_time_init();85 86    // needed to initialize f16 tables87    {88        struct ggml_init_params params = { 0, NULL, false };89        struct ggml_context * ctx = ggml_init(params);90        ggml_free(ctx);91    }92}93 94void llama_numa_init(enum ggml_numa_strategy numa) {95    if (numa != GGML_NUMA_STRATEGY_DISABLED) {96        auto * dev = ggml_backend_dev_by_type(GGML_BACKEND_DEVICE_TYPE_CPU);97        GGML_ASSERT(dev && "CPU backend is not loaded");98        auto * reg = ggml_backend_dev_backend_reg(dev);99        auto * numa_init_fn = (decltype(ggml_numa_init) *) ggml_backend_reg_get_proc_address(reg, "ggml_backend_cpu_numa_init");100        if (numa_init_fn) {101            numa_init_fn(numa);102        }103    }104}105 106void llama_backend_free(void) {107    ggml_quantize_free();108}109 110int64_t llama_time_us(void) {111    return ggml_time_us();112}113 114// Returns 0 on success, -1 on error, and -2 on cancellation via llama_progress_callback115static int llama_model_load(struct gguf_context * metadata, llama_model_set_tensor_data_t set_tensor_data, void * set_tensor_data_ud,116        const std::string & fname, std::vector<std::string> & splits, FILE * file, llama_model & model, llama_model_params & params) {117    // loading time will be recalculated after the first eval, so118    // we take page faults deferred by mmap() into consideration119    model.t_load_us = 0;120    time_meas tm(model.t_load_us);121 122    model.t_start_us = tm.t_start_us;123 124    try {125        llama_model_loader ml(metadata, set_tensor_data, set_tensor_data_ud, fname, splits, file, params.use_mmap, params.use_direct_io,126            params.check_tensors, params.no_alloc, params.kv_overrides, params.tensor_buft_overrides);127 128        ml.print_info();129 130        model.hparams.vocab_only = params.vocab_only;131        model.hparams.no_alloc   = params.no_alloc;132 133        try {134            model.load_arch(ml);135        } catch(const std::exception & e) {136            throw std::runtime_error("error loading model architecture: " + std::string(e.what()));137        }138        try {139            model.load_hparams(ml);140        } catch(const std::exception & e) {141            throw std::runtime_error("error loading model hyperparameters: " + std::string(e.what()));142        }143        if (model.arch == LLM_ARCH_CLIP) {144            throw std::runtime_error("CLIP cannot be used as main model, use it with --mmproj instead");145        }146        try {147            model.load_vocab(ml);148        } catch(const std::exception & e) {149            throw std::runtime_error("error loading model vocabulary: " + std::string(e.what()));150        }151 152        model.load_stats(ml);153        model.print_info();154 155        if (params.vocab_only) {156            LLAMA_LOG_INFO("%s: vocab only - skipping tensors\n", __func__);157            return 0;158        }159 160        if (!model.load_tensors(ml)) {161            return -2;162        }163    } catch (const std::exception & err) {164        LLAMA_LOG_ERROR("%s: error loading model: %s\n", __func__, err.what());165        return -1;166    }167 168    return 0;169}170 171static struct llama_model * llama_model_load_from_file_impl(172        struct gguf_context * metadata,173        llama_model_set_tensor_data_t set_tensor_data,174        void * set_tensor_data_ud,175        const std::string & path_model,176        std::vector<std::string> & splits,177        FILE * file,178        struct llama_model_params params) {179    {180        int n_sources_defined = 0;181        if (metadata != nullptr) {182            n_sources_defined++;183        }184        if (!path_model.empty()) {185            n_sources_defined++;186        }187        if (file != nullptr) {188            n_sources_defined++;189        }190        if (n_sources_defined != 1) {191            LLAMA_LOG_ERROR("%s: exactly one out metadata, path_model, and file must be defined\n", __func__);192            return nullptr;193        }194    }195    ggml_time_init();196 197    if (!params.vocab_only && ggml_backend_reg_count() == 0) {198        LLAMA_LOG_ERROR("%s: no backends are loaded. hint: use ggml_backend_load() or ggml_backend_load_all() to load a backend before calling this function\n", __func__);199        return nullptr;200    }201 202    unsigned cur_percentage = 0;203    if (params.progress_callback == NULL) {204        params.progress_callback_user_data = &cur_percentage;205        params.progress_callback = [](float progress, void * ctx) {206            unsigned * cur_percentage_p = (unsigned *) ctx;207            unsigned percentage = (unsigned) (100 * progress);208            while (percentage > *cur_percentage_p) {209                *cur_percentage_p = percentage;210                LLAMA_LOG_CONT(".");211                if (percentage >= 100) {212                    LLAMA_LOG_CONT("\n");213                }214            }215            return true;216        };217    }218 219    llama_model * model = new llama_model(params);220 221    // create list of devices to use with this model222    if (params.devices) {223        if (params.split_mode == LLAMA_SPLIT_MODE_TENSOR) {224            size_t n_devs = 0;225            while (params.devices[n_devs]) {226                n_devs++;227            }228            if (n_devs == 0) {229                LLAMA_LOG_ERROR("%s: LLAMA_SPLIT_MODE_TENSOR needs >= 1 devices\n", __func__);230                return nullptr;231            }232            LLAMA_LOG_INFO("%s: creating a Meta device with %zu devices\n", __func__, n_devs);233            for (size_t i = 0; i < n_devs; ++i) {234                LLAMA_LOG_INFO("%s: - device %zu: %s\n", __func__, i, ggml_backend_dev_name(params.devices[i]));235            }236            model->get_split_state_ud.n_devices = n_devs;237            model->get_split_state_ud.model = model;238            model->devices.push_back({239                true, ggml_backend_meta_device(240                params.devices, n_devs, llama_meta_device_get_split_state, &model->get_split_state_ud)241            });242        } else {243            for (ggml_backend_dev_t * dev = params.devices; *dev; ++dev) {244                model->devices.push_back({false, *dev});245            }246        }247    } else {248        // default device selection249 250        // build list of available devices251        std::vector<llama_device> gpus;252        std::vector<llama_device> igpus;253        std::vector<llama_device> rpc_servers;254 255        if (params.split_mode == LLAMA_SPLIT_MODE_TENSOR) {256            std::vector<ggml_backend_dev_t> devs;257            devs.reserve(ggml_backend_dev_count());258            for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {259                auto * dev = ggml_backend_dev_get(i);260                if (ggml_backend_dev_buffer_type(dev) == ggml_backend_cpu_buffer_type()) {261                    LLAMA_LOG_INFO("%s: skipping %s (%s) for tensor parallelism\n", __func__, ggml_backend_dev_name(dev), ggml_backend_dev_description(dev));262                    continue;263                }264                devs.push_back(dev);265            }266            if (devs.empty()) {267                LLAMA_LOG_ERROR("%s: LLAMA_SPLIT_MODE_TENSOR needs >= 1 devices\n", __func__);268                return nullptr;269            }270 271            LLAMA_LOG_INFO("%s: creating a Meta device for tensor parallelism from %zu devices:\n", __func__, devs.size());272            for (size_t i = 0; i < devs.size(); ++i) {273                LLAMA_LOG_INFO("%s: - device %zu: %s (%s)\n", __func__, i, ggml_backend_dev_name(devs[i]), ggml_backend_dev_description(devs[i]));274            }275 276            GGML_ASSERT(!devs.empty());277            model->get_split_state_ud.n_devices = devs.size();278            model->get_split_state_ud.model     = model;279            gpus.push_back({280                true, ggml_backend_meta_device(281                devs.data(), devs.size(), llama_meta_device_get_split_state, &model->get_split_state_ud)282            });283        } else {284            for (size_t i = 0; i < ggml_backend_dev_count(); ++i) {285                ggml_backend_dev_t dev = ggml_backend_dev_get(i);286                switch (ggml_backend_dev_type(dev)) {287                    case GGML_BACKEND_DEVICE_TYPE_CPU:288                    case GGML_BACKEND_DEVICE_TYPE_ACCEL:289                        // skip CPU backends since they are handled separately290                        break;291 292                    case GGML_BACKEND_DEVICE_TYPE_GPU: {293                        ggml_backend_reg_t reg = ggml_backend_dev_backend_reg(dev);294                        if (ggml_backend_reg_name(reg) == std::string("RPC")) {295                            rpc_servers.push_back({false, dev});296                        } else {297                            // check if there is already a GPU with the same device id298                            ggml_backend_dev_props props;299                            ggml_backend_dev_get_props(dev, &props);300                            auto it = std::find_if(gpus.begin(), gpus.end(), [&props](const llama_device & d) {301                                ggml_backend_dev_props d_props;302                                ggml_backend_dev_get_props(d.dev, &d_props);303                                if (props.device_id && d_props.device_id) {304                                    return strcmp(props.device_id, d_props.device_id) == 0;305                                }306                                return false;307                            });308 309                            if (it != gpus.end()) {310                                LLAMA_LOG_INFO("%s: skipping device %s (%s) with id %s - already using device %s (%s) with the same id\n",311                                        __func__,312                                        ggml_backend_dev_name(dev), ggml_backend_dev_description(dev),313                                        props.device_id ? props.device_id : "unknown id",314                                        ggml_backend_dev_name(it->dev), ggml_backend_dev_description(it->dev));315                            } else {316                                gpus.push_back({false, dev});317                            }318                        }319                        break;320                    }321 322                    case GGML_BACKEND_DEVICE_TYPE_IGPU:323                        igpus.push_back({false, dev});324                        break;325                    case GGML_BACKEND_DEVICE_TYPE_META:326                        GGML_ABORT("fatal error");327                }328            }329        }330 331        // add RPC servers at the front of the list to minimize network transfers332        model->devices.insert(model->devices.begin(), rpc_servers.begin(), rpc_servers.end());333 334        // add GPUs335        model->devices.insert(model->devices.end(), gpus.begin(), gpus.end());336 337        // add integrated GPUs only if no other devices were found338        if (model->devices.empty()) {339            model->devices.insert(model->devices.end(), igpus.begin(), igpus.end());340        }341    }342 343    // if using single GPU mode, remove all except the main GPU344    if (params.split_mode == LLAMA_SPLIT_MODE_NONE) {345        if (params.main_gpu < 0) {346            model->devices.clear();347        } else {348            if (params.main_gpu >= (int)model->devices.size()) {349                LLAMA_LOG_ERROR("%s: invalid value for main_gpu: %d (available devices: %zu)\n", __func__, params.main_gpu, model->devices.size());350                llama_model_free(model);351                return nullptr;352            }353            llama_device main_gpu = model->devices[params.main_gpu];354            model->devices.clear();355            model->devices.push_back(main_gpu);356        }357    }358 359    for (const auto & dev : model->devices) {360        ggml_backend_dev_props props;361        ggml_backend_dev_get_props(dev.dev, &props);362        LLAMA_LOG_INFO("%s: using device %s (%s) (%s) - %zu MiB free\n", __func__,363                ggml_backend_dev_name(dev.dev), ggml_backend_dev_description(dev.dev),364                props.device_id ? props.device_id : "unknown id",365                props.memory_free/1024/1024);366    }367 368    const int status = llama_model_load(metadata, set_tensor_data, set_tensor_data_ud, path_model, splits, file, *model, params);369    GGML_ASSERT(status <= 0);370    if (status < 0) {371        if (status == -1) {372            LLAMA_LOG_ERROR("%s: failed to load model\n", __func__);373        } else if (status == -2) {374            LLAMA_LOG_INFO("%s: cancelled model load\n", __func__);375        }376 377        llama_model_free(model);378        return nullptr;379    }380 381    return model;382}383 384struct llama_model * llama_model_init_from_user(385        struct gguf_context * metadata,386        llama_model_set_tensor_data_t set_tensor_data,387        void * set_tensor_data_ud,388        struct llama_model_params params) {389    GGML_ASSERT(metadata != nullptr);390    std::string path_model;391    std::vector<std::string> splits = {};392    params.use_mmap = false;393    params.use_extra_bufts = false;394    return llama_model_load_from_file_impl(metadata, set_tensor_data, set_tensor_data_ud, path_model, splits, /*file*/ nullptr, params);395}396// deprecated397struct llama_model * llama_load_model_from_file(398        const char * path_model,399        struct llama_model_params params) {400    return llama_model_load_from_file(path_model, params);401}402 403struct llama_model * llama_model_load_from_file(404        const char * path_model,405        struct llama_model_params params) {406    std::vector<std::string> splits = {};407    return llama_model_load_from_file_impl(nullptr, nullptr, nullptr, path_model, splits, /*file*/ nullptr, params);408}409 410struct llama_model * llama_model_load_from_splits(411        const char ** paths,412        size_t n_paths,413        struct llama_model_params params) {414    std::vector<std::string> splits;415    if (n_paths == 0) {416        LLAMA_LOG_ERROR("%s: list of splits is empty\n", __func__);417        return nullptr;418    }419    splits.reserve(n_paths);420    for (size_t i = 0; i < n_paths; ++i) {421        splits.push_back(paths[i]);422    }423    return llama_model_load_from_file_impl(nullptr, nullptr, nullptr, splits.front(), splits, /*file*/ nullptr, params);424}425 426struct llama_model * llama_model_load_from_file_ptr(FILE * file, struct llama_model_params params) {427    if (!file) {428        LLAMA_LOG_ERROR("%s: file is NULL\n", __func__);429        return nullptr;430    }431    std::string path_model;432    std::vector<std::string> splits = {};433    return llama_model_load_from_file_impl(nullptr, nullptr, nullptr, path_model, splits, file, params);434}435 436void llama_model_save_to_file(const struct llama_model * model, const char * path_model) {437    llama_model_saver ms(model);438    ms.add_kv_from_model();439    ms.add_tensors_from_model();440    ms.save(path_model);441}442 443//444// chat templates445//446 447int32_t llama_chat_apply_template(448                              const char * tmpl,449         const struct llama_chat_message * chat,450                                  size_t   n_msg,451                                    bool   add_ass,452                                    char * buf,453                                 int32_t   length) {454    const std::string curr_tmpl(tmpl == nullptr ? "chatml" : tmpl);455 456    // format the chat to string457    std::vector<const llama_chat_message *> chat_vec;458    chat_vec.resize(n_msg);459    for (size_t i = 0; i < n_msg; i++) {460        chat_vec[i] = &chat[i];461    }462 463    std::string formatted_chat;464    llm_chat_template detected_tmpl = llm_chat_detect_template(curr_tmpl);465    if (detected_tmpl == LLM_CHAT_TEMPLATE_UNKNOWN) {466        return -1;467    }468    int32_t res = llm_chat_apply_template(detected_tmpl, chat_vec, formatted_chat, add_ass);469    if (res < 0) {470        return res;471    }472    if (buf && length > 0) {473        strncpy(buf, formatted_chat.c_str(), length);474    }475    return res;476}477 478//479// model split480//481 482int32_t llama_split_path(483    char * split_path,484    size_t maxlen,485    const char * path_prefix,486    int32_t split_no,487    int32_t split_count) {488 489    static const char * const SPLIT_PATH_FORMAT = "%s-%05d-of-%05d.gguf";490 491    const int written = snprintf(492        split_path,493        maxlen,494        SPLIT_PATH_FORMAT,495        path_prefix,496        split_no + 1,497        split_count498    );499 500    if (written < 0 || (size_t) written >= maxlen) {501        return 0;502    }503 504    return (int32_t) written;505}506 507int32_t llama_split_prefix(508    char * split_prefix,509    size_t maxlen,510    const char * split_path,511    int32_t split_no,512    int32_t split_count) {513 514    const std::string str_split_path(split_path);515 516    char postfix[32];517    snprintf(postfix, sizeof(postfix), "-%05d-of-%05d.gguf", split_no + 1, split_count);518 519    const std::string str_postfix(postfix);520    if (str_split_path.size() <= str_postfix.size()) {521        return 0;522    }523 524    const size_t size_prefix = str_split_path.size() - str_postfix.size();525 526    if (str_split_path.compare(size_prefix, std::string::npos, str_postfix) == 0) {527        const size_t copy_len = std::min(size_prefix + 1, maxlen);528        snprintf(split_prefix, copy_len, "%s", split_path);529 530        return (int32_t) size_prefix;531    }532 533    return 0;534}535 536const char * llama_print_system_info(void) {537    static std::string s;538    s.clear(); // Clear the string, since it's static, otherwise it will accumulate data from previous calls.539 540    for (size_t i = 0; i < ggml_backend_reg_count(); i++) {541        auto * reg = ggml_backend_reg_get(i);542        auto * get_features_fn = (ggml_backend_get_features_t) ggml_backend_reg_get_proc_address(reg, "ggml_backend_get_features");543        if (get_features_fn) {544            ggml_backend_feature * features = get_features_fn(reg);545            s += ggml_backend_reg_name(reg);546            s += " : ";547            for (; features->name; features++) {548                s += features->name;549                s += " = ";550                s += features->value;551                s += " | ";552            }553        }554    }555 556    return s.c_str();557}558 559