目录
目录README.md

llama.cpp for Loongarch64

本项目基于 llama.cpp 改进,针对国产架构 LoongArch64 在软件库和工具链方面的原生支持适配问题,设计实现龙芯架构专用的大模型推理框架

展示内容同步在PPT中

1. 部署指南

1.1 构建编译

推荐创建系统的 workspace 目录,并在创建的目录内创建相关项目工作目录。

mkdir -p ~/workspace && cd ~/workspace

之后的构建流程:

  1. 克隆仓库(免当前设备已有对于llama.cpp的工作,这里重命名为 llama.cpp-loongarch64,也可以直接在原来的目录,创建新分支后进行):

    git clone https://github.com/ggml-org/llama.cpp.git llama.cpp-loongarch64
    cd llama.cpp-loongarch64
    git checkout 6385b843a8dc8e15b8362196039720c58dd79fa2
  2. 应用补丁:

    wget https://gitee.com/sdu-aes-lab/llama.cpp-for-loongarch64-archive/raw/master/patches/llama-loongarch64.patch
    git am --whitespace=fix < llama-loongarch64.patch
  3. 替换文件:

    将 ggml-cpu 放到 ggml/src 文件夹中替换原文件;将 src 放到仓库根目录替换原 src 文件夹;将 main 文件夹放到 tools 文件夹中替换原文件

  4. 构建:

    mkdir build-loongarch64 && cd build-loongarch64
    ../once.sh

构建完成后,已测试可在 loongarch64 设备上运行的 llama.cpp 默认位于(成功执行会提示实际位置):

~/workspace/llama.cpp-loongarch64/build-loongarch64/install/

将其 intall 目录的 内容 拷贝到目标设备的 /usr/local/ 即可。

该流程在新设备的重新构建编译测试成功:

该流程在新设备的重新构建编译测试成功图片

2. 测试报告

2.1 内容测试

按照前面的流程,编译成功的 ~/workspace/llama.cpp-loongarch64/build-loongarch64/install/bin/llama-cli 移动到目标 loongarch64 设备的 /usr/local/bin/llama-cli

执行尝试:(-m 后面是模型.gguf的路径位置):

/usr/local/bin/llama-cli -m ../models/Llama-3.2-1B-Instruct.Q4_K_M.gguf -p "say hello to me" --no-warmup

# 或

/usr/local/bin/llama-cli -m ../models/Llama-3.2-1B-Instruct.Q4_K_M.gguf -p "say hello to me"

2.2 测试结果

  1. 整体测试:

整体图片

执行成功的板上输出:

执行成功的板上输出图片

执行成功的运行时间等记录:

执行成功的运行时间等记录图片

  1. 测试 1 + 1

1+1询问:

1+1询问

1+1出结果:

1+1出结果

这里用时 [10分33.60 - 6分10.22 = 4分23.38]

相同的询问,为初始化后的第二次询问,计算机(i5-11320H)用时 4秒,龙芯 2K0300B 用时 4分23.38秒。

  1. 测试结束

结束的 perf print:

llama_perf_sampler_print:    sampling time =      72.14 ms /    29 runs   (    2.49 ms per token,   402.02 tokens per second)
llama_perf_context_print:        load time =   31424.47 ms
llama_perf_context_print: prompt eval time =  404154.08 ms /    55 tokens ( 7348.26 ms per token,     0.14 tokens per second)
llama_perf_context_print:        eval time =  313707.92 ms /    20 runs   (15685.40 ms per token,     0.06 tokens per second)
llama_perf_context_print:       total time = 4271548.15 ms /    75 tokens
Interrupted by user

结束perf print

3. 技术方案

3.1 补丁说明

3.1.1 编译器标志修改

文件: Makefile

操作: 修改(禁用SIMD标志)
行数: 2行删除,2行新增

 ifneq ($(filter loongarch64%,$(UNAME_M)),)
-    MK_CFLAGS   += -mlasx
-    MK_CXXFLAGS += -mlasx
+    # MK_CFLAGS   += -mlasx
+    # MK_CXXFLAGS += -mlasx
 endif

目的: 禁用LASX(LoongArch高级SIMD扩展)编译器标志。补丁中的注释说明:

  • “删除原来的C++编译器标志(启用LASX指令集)”
  • “只有 LA364 部分具备 LSX 128-bit;LA132 完全没有向量单元;芯片整体 不支持 LASX”
  • “不要开 -mlasx,只用 -mlsx 或直接 -mno-lasx -mno-lsx 禁用向量指令,保守编译”

这是避免SIMD兼容性问题的保守编译方法。

3.1.2 库链接修改

文件: ggml/src/CMakeLists.txt

操作: 修改(增强库链接) 行数: 1行删除,3行新增

 if (CMAKE_SYSTEM_NAME MATCHES "Linux")
-    target_link_libraries(ggml PRIVATE dl)
+    target_link_libraries(ggml PRIVATE dl stdc++fs)
+else()
+    target_link_libraries(ggml PRIVATE stdc++fs)
 endif()

目的: 为所有平台添加stdc++fs(C++文件系统库)链接,Linux系统采用条件链接。这确保文件系统操作在不同环境中正常工作。

文件: ggml/src/ggml-rpc/CMakeLists.txt

操作: 修改(Windows库链接)
行数: 1行删除,1行新增

 if (WIN32)
-    target_link_libraries(ggml-rpc PRIVATE ws2_32)
+    target_link_libraries(ggml-rpc PRIVATE ws2_32 stdc++fs)
 endif()

目的: 为Windows构建的RPC组件添加stdc++fs链接。

3.1.3 工具链基础设施

文件: loongarch64-asserts/setEnv.sh

操作: 创建(新文件) 行数: +5行新增

#!/bin/bash
LOONGARCH64_ROOT_PATH=$(realpath "../loongarch64-asserts/toolchain_gcc83_16")

export LOONGARCH64_ROOT_PATH="$LOONGARCH64_ROOT_PATH"
export PATH="$LOONGARCH64_ROOT_PATH/bin:$PATH"

目的: 环境设置脚本,功能包括:

  • 设置LoongArch64工具链根路径
  • 将工具链的bin目录添加到PATH
  • 启用交叉编译环境
文件: once.sh

操作: 创建(新可执行脚本) 行数: +29行新增

#!/bin/bash

# 目录验证
if [[ ! "$(pwd)" =~ build ]]; then
    echo "请在包含 'build' 词汇的目录下运行此脚本。"
    exit 1
fi

# 工具链下载和设置
if [ ! -d "../loongarch64-asserts/toolchain_gcc83_16" ] || [ -z "$(ls -A ../loongarch64-asserts/toolchain_gcc83_16)" ]; then
    wget https://ftp.loongnix.cn/toolchain/gcc/release/loongarch/gcc8/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -P ../loongarch64-asserts
    mkdir -p ../loongarch64-asserts/toolchain_gcc83_16
    tar -xf ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -C ../loongarch64-asserts/toolchain_gcc83_16 --strip-components=1
    rm ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz
fi

# 构建目录清理
rm -rf $(pwd)/*
rm -rf $(pwd)/.[!.]*
rm -rf $(pwd)/.??*
echo "清理了 $(pwd) 目录下的所有文件和隐藏文件。"

# 交叉编译构建
if source ../loongarch64-asserts/setEnv.sh; then
    cmake .. -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=loongarch64 -DCMAKE_C_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-g++ -DCMAKE_FIND_ROOT_PATH=$LOONGARCH64_ROOT_PATH -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx" -DCMAKE_CXX_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx -Wno-unused-variable -Wno-maybe-uninitialized" -DCMAKE_INSTALL_PREFIX=./install -DLLAMA_CURL=OFF -DGGML_LASX=OFF -DGGML_LSX=OFF -DLLAMA_CUDA=OFF -DLLAMA_METAL=OFF -DGGML_OPENMP=OFF
    make -j4
    make install
else 
    echo "未正确使用 git patch。"
    exit 1
fi

echo -e "\nbash
#!/bin/bash

# 目录验证
if [[ ! "$(pwd)" =~ build ]]; then
    echo "请在包含 'build' 词汇的目录下运行此脚本。"
    exit 1
fi

# 工具链下载和设置
if [ ! -d "../loongarch64-asserts/toolchain_gcc83_16" ] || [ -z "$(ls -A ../loongarch64-asserts/toolchain_gcc83_16)" ]; then
    wget https://ftp.loongnix.cn/toolchain/gcc/release/loongarch/gcc8/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -P ../loongarch64-asserts
    mkdir -p ../loongarch64-asserts/toolchain_gcc83_16
    tar -xf ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -C ../loongarch64-asserts/toolchain_gcc83_16 --strip-components=1
    rm ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz
fi

# 构建目录清理
rm -rf $(pwd)/*
rm -rf $(pwd)/.[!.]*
rm -rf $(pwd)/.??*
echo "清理了 $(pwd) 目录下的所有文件和隐藏文件。"

# 交叉编译构建
if source ../loongarch64-asserts/setEnv.sh; then
    cmake .. -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=loongarch64 -DCMAKE_C_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-g++ -DCMAKE_FIND_ROOT_PATH=$LOONGARCH64_ROOT_PATH -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx" -DCMAKE_CXX_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx -Wno-unused-variable -Wno-maybe-uninitialized" -DCMAKE_INSTALL_PREFIX=./install -DLLAMA_CURL=OFF -DGGML_LASX=OFF -DGGML_LSX=OFF -DLLAMA_CUDA=OFF -DLLAMA_METAL=OFF -DGGML_OPENMP=OFF
    make -j4
    make install
else 
    echo "未正确使用 git patch。"
    exit 1
fi

echo -e "\n\033[32m构建和安装完成,位于 $(pwd)/install 目录下。\033[0m\n"
33[32m构建和安装完成,位于 $(pwd)/install 目录下。bash
#!/bin/bash

# 目录验证
if [[ ! "$(pwd)" =~ build ]]; then
    echo "请在包含 'build' 词汇的目录下运行此脚本。"
    exit 1
fi

# 工具链下载和设置
if [ ! -d "../loongarch64-asserts/toolchain_gcc83_16" ] || [ -z "$(ls -A ../loongarch64-asserts/toolchain_gcc83_16)" ]; then
    wget https://ftp.loongnix.cn/toolchain/gcc/release/loongarch/gcc8/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -P ../loongarch64-asserts
    mkdir -p ../loongarch64-asserts/toolchain_gcc83_16
    tar -xf ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz -C ../loongarch64-asserts/toolchain_gcc83_16 --strip-components=1
    rm ../loongarch64-asserts/loongson-gnu-toolchain-8.3-x86_64-loongarch64-linux-gnu-rc1.6.tar.xz
fi

# 构建目录清理
rm -rf $(pwd)/*
rm -rf $(pwd)/.[!.]*
rm -rf $(pwd)/.??*
echo "清理了 $(pwd) 目录下的所有文件和隐藏文件。"

# 交叉编译构建
if source ../loongarch64-asserts/setEnv.sh; then
    cmake .. -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=loongarch64 -DCMAKE_C_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-gcc -DCMAKE_CXX_COMPILER=$LOONGARCH64_ROOT_PATH/bin/loongarch64-linux-gnu-g++ -DCMAKE_FIND_ROOT_PATH=$LOONGARCH64_ROOT_PATH -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER -DCMAKE_FIND_ROOT_PATH_MODE_LIBRARY=ONLY -DCMAKE_FIND_ROOT_PATH_MODE_INCLUDE=ONLY -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx" -DCMAKE_CXX_FLAGS="-O2 -march=loongarch64 -mabi=lp64d -mno-lsx -mno-lasx -Wno-unused-variable -Wno-maybe-uninitialized" -DCMAKE_INSTALL_PREFIX=./install -DLLAMA_CURL=OFF -DGGML_LASX=OFF -DGGML_LSX=OFF -DLLAMA_CUDA=OFF -DLLAMA_METAL=OFF -DGGML_OPENMP=OFF
    make -j4
    make install
else 
    echo "未正确使用 git patch。"
    exit 1
fi

echo -e "\n\033[32m构建和安装完成,位于 $(pwd)/install 目录下。\033[0m\n"
33[0m\n"

目的: 自动化构建脚本,功能包括:

  • 验证在构建目录中执行
  • 下载并提取LoongArch64 GCC 8.3工具链
  • 清理构建目录
  • 配置特定标志的交叉编译:
    • 目标:LoongArch64 Linux
    • ABI:lp64d(64位long和指针,双精度浮点)
    • 禁用SIMD:-mno-lsx -mno-lasx
    • 禁用功能:CURL、LASX、LSX、CUDA、Metal、OpenMP
    • 优化级别:O2
  • 构建并安装项目

3.1.4 全面的库链接更新

补丁系统性地为项目中所有可执行目标添加stdc++fs链接:

测试框架

文件: tests/CMakeLists.txt 操作: 4处修改

-    target_link_libraries(${TEST_TARGET} PRIVATE common)
+    target_link_libraries(${TEST_TARGET} PRIVATE common stdc++fs)

-    target_link_libraries(${TEST_TARGET} PRIVATE common)
+    target_link_libraries(${TEST_TARGET} PRIVATE common stdc++fs)

-target_link_libraries(${LLAMA_TEST_NAME} PRIVATE mtmd)
+target_link_libraries(${LLAMA_TEST_NAME} PRIVATE mtmd stdc++fs)

-target_link_libraries(${TEST_TARGET} PRIVATE llama)
+target_link_libraries(${TEST_TARGET} PRIVATE llama stdc++fs)
工具可执行文件

文件: 多个工具CMakeLists.txt文件 操作: 跨工具的17处修改

修改的文件:

  • tools/batched-bench/CMakeLists.txt
  • tools/cvector-generator/CMakeLists.txt
  • tools/gguf-split/CMakeLists.txt
  • tools/imatrix/CMakeLists.txt
  • tools/llama-bench/CMakeLists.txt
  • tools/main/CMakeLists.txt
  • tools/mtmd/CMakeLists.txt(5处修改)
  • tools/perplexity/CMakeLists.txt
  • tools/quantize/CMakeLists.txt
  • tools/rpc/CMakeLists.txt
  • tools/run/CMakeLists.txt
  • tools/server/CMakeLists.txt
  • tools/tokenize/CMakeLists.txt

模式: 所有修改都遵循相同的模式:

-target_link_libraries(${TARGET} PRIVATE [existing_libs])
+target_link_libraries(${TARGET} PRIVATE [existing_libs] stdc++fs)

目的: 确保所有可执行文件都能访问C++文件系统库功能,这对以下方面至关重要:

  • 文件路径操作
  • 跨平台文件系统兼容性
  • 现代C++文件系统功能

3.2 函数修改说明

3.2.1 LoongArch64特定量化优化

文件: ggml/src/ggml-cpu/arch/loongarch/quants.c 位置: 第37-77行

实现
// LoongArch64优化的Q4_K反量化
void dequantize_row_q4_K_lsx(const block_q4_K * GGML_RESTRICT x, float * GGML_RESTRICT y, int64_t k) {
    assert(k % QK_K == 0);
    const int nb = k / QK_K;
    
    // LoongArch64优化的标量实现(绕过LSX SIMD问题)
    for (int i = 0; i < nb; i++) {
        const uint8_t * q = x[i].qs;
        const float d   = GGML_FP16_TO_FP32(x[i].d);
        const float min = GGML_FP16_TO_FP32(x[i].dmin);
        
        // 以64元素块处理,使用展开循环提升性能
        // 每次8字节的手动循环展开
        for (int l = 0; l < 32; l += 8) {
            uint8_t q0 = q[l+0], q1 = q[l+1], q2 = q[l+2], q3 = q[l+3];
            uint8_t q4 = q[l+4], q5 = q[l+5], q6 = q[l+6], q7 = q[l+7];
            
            // 提取并转换4位值为浮点数(16个操作展开)
            y[l*2+0]  = d1 * (q0 & 0xF) - m1;  y[l*2+1]  = d2 * (q0 >> 4) - m2;
            // ... 完整展开的另外14个类似操作
        }
    }
}
为什么进行此优化
  • 问题: 原始LSX SIMD实现导致性能问题(注释中提到34秒每token)
  • 解决方案: 通过手动循环展开的自定义标量实现提供更好的缓存效率
  • 影响: 绕过SIMD兼容性问题,同时通过算法优化保持性能

3.2.2 受限环境的内存管理优化

文件: src/llama-mmap.cpp 位置: 第279-284行

实现
// LoongArch64优化:在内存受限环境中使用MAP_PRIVATE
#ifdef __loongarch64
int flags = MAP_PRIVATE;  // 写时复制减少内存压力
#else
int flags = MAP_SHARED;
#endif
为什么进行此优化
  • 问题: 400MB RAM限制需要仔细的内存管理
  • 解决方案: 使用MAP_PRIVATE和写时复制语义替代MAP_SHARED
  • 影响: 通过惰性分配和写时复制行为减少内存压力

3.2.3. 模型加载优化

文件: src/llama-model-loader.cpp 位置: 第689-704行

实现
// LoongArch64内存优化:为内存受限环境强制内存映射
#ifdef __loongarch64
if (use_mmap) {
    LLAMA_LOG_INFO("%s: 检测到LoongArch64 - 为400MB RAM限制启用积极内存映射\n", __func__);
}
LLAMA_LOG_INFO("%s: LoongArch64优化 - 减少上下文大小,禁用验证,优化Q4_K反量化\n", __func__);
#endif

// LoongArch64优化:禁用张量验证以加快加载速度
#ifdef __loongarch64
this->check_tensors = false;  // 
#else
this->check_tensors = check_tensors;
#endif
为什么进行此优化
  • 问题: 由于大量张量验证,模型加载需要124+秒
  • 解决方案: 专门为LoongArch64目标平台禁用张量验证
  • 影响: 大幅减少模型加载时间,同时保持推理准确性

3.2.4 构建系统优化

文件: ggml/src/ggml-cpu/CMakeLists.txt 位置: 第347-362行

实现
elseif (${CMAKE_SYSTEM_PROCESSOR} MATCHES "loongarch64")
    message(STATUS "检测到loongarch64")

    list(APPEND ARCH_FLAGS -march=loongarch64)
    # 暂时禁用LSX/LASX以避免SIMD兼容性问题
    # if (GGML_LASX)
    #     list(APPEND ARCH_FLAGS -mlasx)
    # endif()
    
    # 添加LoongArch64架构特定优化
    list(APPEND GGML_CPU_SOURCES
        ggml-cpu/arch/loongarch/quants.c
    )
为什么进行此优化
  • 问题: 通用构建配置不针对LoongArch64特性优化
  • 解决方案: 具有选择性SIMD处理的架构特定构建配置
  • 影响: 确保最优代码生成并包含自定义优化

3.2.5 综合性基准测试系统

文件: tools/main/main.cpp 位置: 第46-168行(辅助函数),第698-975行(集成)

内存使用跟踪
double get_memory_usage_mb() {
    std::ifstream status_file("/proc/self/status");
    std::string line;
    while (std::getline(status_file, line)) {
        if (line.find("VmRSS:") == 0) {
            std::istringstream iss(line);
            std::string label, value, unit;
            iss >> label >> value >> unit;
            return std::stod(value) / 1024.0; // 将KB转换为MB
        }
    }
    return 0.0;
}

double get_swap_usage_mb() {
    std::ifstream status_file("/proc/self/status");
    std::string line;
    while (std::getline(status_file, line)) {
        if (line.find("VmSwap:") == 0) {
            std::istringstream iss(line);
            std::string label, value, unit;
            iss >> label >> value >> unit;
            return std::stod(value) / 1024.0; // 将KB转换为MB
        }
    }
    return 0.0;
}
性能指标日志记录
void log_token_generation_timing(
    const std::chrono::high_resolution_clock::time_point& generation_start_time,
    const std::chrono::high_resolution_clock::time_point& first_token_time,
    int tokens_generated_count) {
    
    auto generation_end_time = std::chrono::high_resolution_clock::now();
    
    // 计算TTFT(首次token时间)
    auto ttft_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
        first_token_time - generation_start_time);
    
    // 计算总生成时间
    auto total_duration = std::chrono::duration_cast<std::chrono::milliseconds>(
        generation_end_time - generation_start_time);
    
    // 计算每秒token数
    double tokens_per_second = 0.0;
    if (total_duration.count() > 0) {
        tokens_per_second = (tokens_generated_count * 1000.0) / total_duration.count();
    }
    
    // 获取当前内存使用量
    double current_rss = get_memory_usage_mb();
    double current_swap = get_swap_usage_mb();
    
    // 同时记录到控制台和文件
    std::cout << "=== 性能指标 ===" << std::endl;
    std::cout << "TTFT(首次token时间): " << ttft_duration.count() << " ms" << std::endl;
    std::cout << "总生成时间: " << total_duration.count() << " ms" << std::endl;
    std::cout << "生成token数: " << tokens_generated_count << std::endl;
    std::cout << "Token/秒: " << std::fixed << std::setprecision(2) << tokens_per_second << std::endl;
    std::cout << "RSS内存使用: " << std::fixed << std::setprecision(1) << current_rss << " MB" << std::endl;
    std::cout << "交换空间使用: " << std::fixed << std::setprecision(1) << current_swap << " MB" << std::endl;
    
    // 追加到性能日志文件
    std::ofstream log_file("llama_performance.log", std::ios::app);
    if (log_file.is_open()) {
        log_file << "TTFT: " << ttft_duration.count() << " ms, "
                 << "总计: " << total_duration.count() << " ms, "
                 << "Token数: " << tokens_generated_count << ", "
                 << "Token/s: " << std::fixed << std::setprecision(2) << tokens_per_second << ", "
                 << "RSS: " << std::fixed << std::setprecision(1) << current_rss << " MB, "
                 << "交换: " << std::fixed << std::setprecision(1) << current_swap << " MB" << std::endl;
        log_file.close();
    }
}
主生成循环中的时序集成
// token生成性能测量的计时
auto token_generation_start_time = std::chrono::high_resolution_clock::now();
auto first_token_time = std::chrono::high_resolution_clock::now();
bool first_token_recorded = false;
int tokens_generated_count = 0;

// 在生成循环内:
if (!first_token_recorded) {
    first_token_time = std::chrono::high_resolution_clock::now();
    first_token_recorded = true;
}

// token计数和处理...
tokens_generated_count++;

// 完成时:
log_token_generation_timing(token_generation_start_time, first_token_time, tokens_generated_count);
为什么进行此优化
  • 竞赛要求: 综合基准测试对于测量所需的40-60%性能提升至关重要
  • 内存限制: 对于在400MB + 交换限制内跟踪内存使用至关重要
  • 验证: 提供量化指标来验证优化
  • 高精度: 使用std::chrono::high_resolution_clock实现微秒级精度
  • 非侵入性: 最小开销,不影响推理性能
  • 全面性: 捕获延迟(TTFT)和吞吐量指标
关于
534.9 MB
邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

©Copyright 2023 CCF 开源发展委员会
Powered by Trustie& IntelliDE 京ICP备13000930号