Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MNN:Sync Sync Internal 2.9.0 #2863

Merged
merged 1 commit into from
May 11, 2024
Merged

MNN:Sync Sync Internal 2.9.0 #2863

merged 1 commit into from
May 11, 2024

Conversation

jxt1234
Copy link
Collaborator

@jxt1234 jxt1234 commented May 11, 2024

MNN-LLM 正式合入

增加Transformer相关算子与对应图优化功能

  • 编译 MNN 时打开宏 MNN_SUPPORT_TRANSFORMER_FUSE ,增加对应算子的编译
    • -DMNN_SUPPORT_TRANSFORMER_FUSE=ON
  • 转换模型时加上 --transformerFuse=1 开启Transformer模型相关图优化

新增 LLM 模块

使用方法

构建 LLM 文件包

  • 下载模型,推荐使用魔搭
    • pip install modelscope
    • 执行脚本(以千问7b为例)
from modelscope import snapshot_download
from transformers import AutoModelForCausalLM, AutoTokenizer

# Downloading model checkpoint to a local dir model_dir
model_dir = snapshot_download('qwen/Qwen-7B-Chat')
#model_dir = snapshot_download("modelscope/Llama-2-7b-chat-ms", revision='v1.0.5',
                              ignore_file_pattern=[r'.+\.bin$'])
#model_dir = snapshot_download('qwen/Qwen-1_8B-Chat')
print(model_dir)
  • 使用 MNN 目录下面的 transformers/llm/export/llm_export.py 进行模型导出,把 torch 模型转换成 onnx
    • 示例
      • python3 llm_export.py --embed_bin --embed_bf16 --onnx_path onnx --type Qwen-7B-Chat --path /Users/xtjiang/.cache/modelscope/hub/qwen/Qwen-7B-Chat --export_embed --export_token --mnn_path mnn --export
    • 务必加 --embed_bin 参数,将 embeding 层导出成 bin 文件
    • 完成后会产出两个文件夹
      • onnx
        • llm.onnx
        • tokenizer.txt
        • 其他外置权重数据,不用关注
      • mnn
        • embeddings_bf16.bin
  • 使用 MNNConvert 转换 onnx 模型,并进行量化
    • ./MNNConvert -f ONNX --modelFile onnx/llm.onnx llm.mnn --weightQuantBits=4 --transformerFuse=1 --saveExternalData
    • 一般需要20-30 分钟,请耐心等待
    • 产出 llm.mnn 与 llm.mnn.weight
  • 建文件夹,组合上述步骤产出的文件,这里以千问7b为例
    • 文件夹名:qwen-7b-int4
    • 包含文件
      • embeddings_bf16.bin
      • llm.mnn
      • llm.mnn.weight
      • tokenizer.txt

编译LLM引擎并使用

  • 编译MNN打开 MNN_BUILD_LLM 宏,编译 transformers/llm/engine 目录,产出 libllm 和 llm_demo

  • 使用 llm_demo 运行 llm

    • 参数:
      • llm.mnn 文件路径
      • forwardtype :0 为 CPU ,3 为 OpenCL
      • Memory | Precision :Memory * 4 + Precision ,如果 memory 和 preicsion 都为 low ,即设为 10
    • 示例:
      • ./llm_demo ../../qwen-7b-int4/llm.mnn 0 10
        • 【然后进行对话】
      • ./llm_demo ../../qwen-7b-int4/llm.mnn 0 10 prompt.txt :使用预设的问题进行测试
  • CPU / GPU

性能测试

  • 8gen1
    | model | CPU 4线程 | | OpenCL | |
    | --- | --- | --- | --- | --- |
    | | prefill | decode | prefill | decode |
    | qwen-1.8b | 207.56 | 35.58 | 28.58 | 20.40 |
    | qwen-7b | 25.86 | 7.5 | 7.95 | 7.70 |
    | llama3-8b | 22.09 | 5.59 | 内存不足 | 内存不足 |

  • 8gen3
    | model | CPU 4线程 | | OpenCL | |
    | --- | --- | --- | --- | --- |
    | | prefill | decode | prefill | decode |
    | qwen-1.8b | 205.70 | 47.07 | 61.25 | 21.56 |
    | qwen-7b | 40.93 | 11.01 | 20.26 | 10.60 |
    | llama3-8b | 36.44 | 7.83 | 19.10 | 2.14 |

  • 注:暂未对 llama3-8b 结构支持 Transformer 相关图优化,因此性能略差

形变缓存机制

背景

对于语音/文本类的模型,往往涉及张量某个维度的逐步变化,这种情况下每次都会进行几何计算、申请内存等操作,导致不可忽略的性能损耗。考虑到输入单个维度变化的情况下,网络中会存在部分算子形状不变,这部分计算是可以去除的。
为了对这种情况进行优化,MNN新增了形变缓存机制,使模型输入形状变化时,形状不变的算子跳过形变相关操作,以提升性能。

原理

  • MNN 通过两个状态去优化Resize过程,先在 Check 状态下寻找不变形状的算子,然后切换到 Fix 状态,分离易变形状与不变形状算子进行处理。对应于 Interpreter.hpp 里面增加两个 SessionMode
    • Session_Resize_Check
    • Session_Resize_Fix
  • Check 状态
    • 存储或检查输入的形状是否与上次一致,对应跳过几何计算阶段,但资源分配阶段不跳过
  • Fix 状态
    • 根据算子的形状不变标志,跳过几何计算与资源分配阶段

基于 Module API 使用

对应 API

  • **Module::**traceOrOptimize

示例

  • 网络输入为 speech ,输出为 out0 ,out1 ,输入大小为: 1,3,X
std::shared_ptr<MNN::Express::Module> net(MNN::Express::Module::load(fileName, {"speech"}, {"out0", "out1"}), MNN::Express::Module::destroy);
net->traceOrOptimize(MNN::Interpreter::Session_Resize_Check);
int validShape[] = {64, 112};
for (int i=0; i<2; ++i) {
    auto varp = MNN::Express::_Input({1, 3, validShape[i]}, MNN::Express::NCHW);
    varp->writeMap<float>();
    auto outputs = net->onForward({varp});
}
net->traceOrOptimize(MNN::Interpreter::Session_Resize_Fix);
// Forward and use output

基于 Intrepreter - Session API使用

相关API

  • Interpreter::setSessionMode

示例

  • 网络输入为 speech ,输出为 out0 ,out1 ,输入大小为: 1,3,X
std::shared_ptr<MNN::Interpreter> net(MNN::Interpreter::createFromFile(fileName), MNN::Interpreter::destroy);
MNN::ScheduleConfig config;
/*Set up config
......
*/
MNN::Session* session = net->createSession(config);
auto input = net->getSessionInput(session, "speech");
auto out0 = net->getSessionOutput(session, "out0");
auto out1 = net->getSessionOutput(session, "out1");
net->setSessionMode(Interpreter::Session_Resize_Check);
/*Resize Session for each valid size Begin*/
/*Demo: */
net->resizeTensor(input, {1, 3, 112});
net->resizeSession(session);
net->resizeTensor(input, {1, 3, 64});
net->resizeSession(session);
/*Resize Session for each valid size End*/
net->setSessionMode(Interpreter::Session_Resize_Fix);

/*Fill input and run session
......
*/

鸿蒙系统支持、功能完善与Github Issue 修正

功能完善

  • 支持华为鸿蒙系统上的编译与运行
    • 参考 MNN/project/harmony 下面的脚本进行编译
  • 增加 WinogradLevel 配置,支持用户设定较低的Winograd 输出计算尺寸 ,以节省内存
    • setSessionHint(WINOGRAD_MEMORY_LEVEL, 0) :使用最低计算尺寸
    • setSessionHint(WINOGRAD_MEMORY_LEVEL, 3) :使用默认计算尺寸
  • 修正 onnx onehot 算子在输入尺寸未知时转换出错问题
  • 修正 Sigmoid / Tanh 等算子量化后出错的问题
  • 优化 Tile 算子的几何计算分解,降低产出的Region数,以减少对应GPU后端的初始化耗时
  • 支持 LayerNorm RMS 模式及相应的图优化
  • 原生支持onnx-external data ,降低 Onnx 大模型转换所需要内存
  • Metal 后端 NC4HW4 布局模式修改为C4NHW4,以优化 batch > 1 的卷积性能
  • Metal 后端支持 BatchMatMul / Gather / GatherND 等对应生成的 Loop 算子
  • Metal 后端支持 GridSampler3D
  • Metal 后端支持可变精度设置
    • precision 为 low / normal 时使用 fp16 存储
    • precision 为 high 时使用 fp32 存储
    • 计算一律使用 fp32
  • CPU 后端修正权值在线反量化模式下,输入输出通道不对齐时出错的问题
  • OpenCL 后端优化 Pooling 算子在 KernelSize 很大时的性能问题
  • OpenCL 后端增加 Kernel 缓存机制,降低部分设备上 resize 耗时
  • 其他Bugfix与优化

相应 Issue 修正

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


xiaying seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@jxt1234 jxt1234 merged commit 92d0b94 into master May 11, 2024
18 of 19 checks passed
@jxt1234 jxt1234 deleted the feature/sync_290 branch May 11, 2024 11:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants