Skip to content

采样、量化与部署 — 代码走读

src/llama-sampler.cpp — 采样器实现

采样器链架构

cpp
// 创建采样器链
struct llama_sampler * chain = llama_sampler_chain_init(
    llama_sampler_chain_default_params());

// 添加采样器(顺序很重要!)
llama_sampler_chain_add(chain, llama_sampler_init_temp(0.8f));
llama_sampler_chain_add(chain, llama_sampler_init_top_k(40));
llama_sampler_chain_add(chain, llama_sampler_init_top_p(0.95f, 1));
llama_sampler_chain_add(chain, llama_sampler_init_dist(LLAMA_DEFAULT_SEED));

// 采样
llama_token token = llama_sampler_sample(chain, ctx, -1);

采样器接口

每个采样器实现统一接口:

cpp
struct llama_sampler_i {
    const char *       (*name)  (const llama_sampler * smpl);
    void               (*accept)(llama_sampler * smpl, llama_token token);
    llama_token        (*apply) (llama_sampler * smpl, llama_context * ctx, int32_t idx);
    void               (*reset) (llama_sampler * smpl);
    void               (*free)  (llama_sampler * smpl);
    struct llama_sampler * (*clone)(const llama_sampler * smpl);
};

Top-P 实现

cpp
// Top-P: 保留累积概率 <= p 的 token
static llama_token llama_sampler_top_p_apply(
    llama_sampler * smpl, llama_context * ctx, int32_t idx) {
    auto * cur_p = llama_sampler_get_candidates(ctx, idx);
    // 按 logit 排序
    // 计算累积 softmax 概率
    // 截断到 top-p
    // 从截断后的候选中采样
}

tools/quantize/ — 量化工具

量化入口:

cpp
// quantize 工具核心
int main(int argc, char ** argv) {
    // 1. 加载源模型
    // 2. 按类型量化每个张量
    // 3. 写入新的 GGUF 文件
}

量化过程:

cpp
// 对每个张量执行量化
for (auto & tensor : model.tensors) {
    switch (quant_type) {
        case GGML_TYPE_Q4_0:
            ggml_quantize_q4_0(src_data, dst_data, n_elements);
            break;
        case GGML_TYPE_Q5_K:
            ggml_quantize_q5_K(src_data, dst_data, n_elements);
            break;
        // ...
    }
}

tools/server/ — HTTP 服务器

cpp
// server 核心循环
int main(int argc, char ** argv) {
    // 1. 解析参数、加载模型
    // 2. 创建 HTTP 服务器 (httplib)
    // 3. 注册 API 路由

    svr.Post("/v1/chat/completions", handle_chat_completion);
    svr.Post("/v1/completions", handle_completion);
    svr.Post("/v1/embeddings", handle_embeddings);

    // 4. 启动事件循环
    svr.listen("0.0.0.0", port);
}

任务队列

cpp
// server 使用任务队列处理并发请求
struct server_task {
    int id;
    llama_token prompt;
    json params;  // temperature, top_p, etc.
};

// 多个请求可以合并到一个 batch 中并行处理

关键函数索引

函数文件说明
llama_sampler_chain_initllama-sampler.cpp创建采样器链
llama_sampler_chain_addllama-sampler.cpp添加采样器
llama_sampler_samplellama-sampler.cpp从 logits 采样 token
llama_sampler_init_top_kllama-sampler.cpp创建 Top-K 采样器
llama_sampler_init_top_pllama-sampler.cpp创建 Top-P 采样器
llama_sampler_init_templlama-sampler.cpp创建温度采样器