音乐播放器
sola的小屋
 
文章 标签
20

Powered by Gridea | Theme: Fog
载入天数...
载入时分秒...
总访问量:  |   访问人数:

InferLLM大模型推理框架项目(13)——计算图的工厂方法实现(src/graph/graph_imp.cpp)

graph_imp.cpp 代码结构与功能实现分析

graph_imp.cpp 是 InferLLM 框架中的一个核心文件,主要实现了计算图的工厂方法,用于根据模型名称创建相应的计算图实例。这个文件虽然简短,但在整个框架中扮演着重要的角色。

1. 文件结构

graph_imp.cpp 文件包含以下几个部分:

  1. 头文件引入

    #include "chatGLM.h"
    #include "ggml_llama.h"
    #include "llama_like.h"
    

    引入了三个头文件,分别对应不同的模型实现:

    • chatGLM.h:包含 ChatGLM 系列模型的定义
    • ggml_llama.h:包含 GGML 格式的 Llama 模型定义
    • llama_like.h:包含类 Llama 架构的模型定义(如 Baichuan 和 Llama2)
  2. 命名空间声明

    using namespace inferllm;
    

    使用 inferllm 命名空间,这是整个框架的主命名空间。

  3. 工厂方法实现

    std::shared_ptr<Graph> Graph::make_graph(
            UserConfig model_config, Device* device, const std::string& name) {
        // 根据模型名称创建相应的计算图实例
    }
    

    实现了 Graph 类的静态方法 make_graph,用于创建计算图实例。

2. 功能实现

2.1 工厂方法 make_graph

make_graph 方法是一个典型的工厂方法,根据传入的模型名称 name 创建相应的计算图实例:

std::shared_ptr<Graph> Graph::make_graph(
        UserConfig model_config, Device* device, const std::string& name) {
    if (name == "llama") {
        return std::make_shared<GgmlLlamaGraph>(model_config, device, name);
    } else if (name == "chatglm") {
        return std::make_shared<ChatGLMGraph>(model_config, device, name);
    } else if (name == "chatglm2") {
        return std::make_shared<ChatGLMGraph2>(model_config, device, name);
    } else if (name == "chatglm3") {
        return std::make_shared<ChatGLMGraph3>(model_config, device, name);
    } else if (name == "baichuan" || name == "llama2") {
        return std::make_shared<LlamaLikeGraph>(model_config, device, name);
    } else {
        INFER_ASSERT(0, "unsupported model.");
    }
}

该方法接收三个参数:

  • model_config:用户配置,包含模型的各种配置参数
  • device:设备指针,指向执行计算的设备(如 CPU 或 GPU)
  • name:模型名称,用于确定创建哪种类型的计算图

根据模型名称,该方法创建以下几种计算图:

  1. "llama":创建 GgmlLlamaGraph 实例,用于处理 GGML 格式的 Llama 模型
  2. "chatglm":创建 ChatGLMGraph 实例,用于处理 ChatGLM 模型
  3. "chatglm2":创建 ChatGLMGraph2 实例,用于处理 ChatGLM2 模型
  4. "chatglm3":创建 ChatGLMGraph3 实例,用于处理 ChatGLM3 模型
  5. "baichuan""llama2":创建 LlamaLikeGraph 实例,用于处理类 Llama 架构的模型

如果传入的模型名称不在上述列表中,则通过 INFER_ASSERT 宏触发断言,提示不支持该模型。

3. 设计模式分析

3.1 工厂模式

graph_imp.cpp 文件实现了典型的工厂模式,具体来说是简单工厂模式(Simple Factory Pattern):

  1. 工厂方法Graph::make_graph 是一个静态工厂方法,负责创建具体的产品(计算图实例)
  2. 抽象产品Graph 是抽象产品,定义了计算图的接口
  3. 具体产品GgmlLlamaGraphChatGLMGraphChatGLMGraph2ChatGLMGraph3LlamaLikeGraph 是具体产品,实现了计算图的接口

这种设计有以下优点:

  • 封装创建逻辑:客户端不需要知道如何创建具体的计算图,只需要提供模型名称
  • 扩展性:可以方便地添加新的模型支持,只需在工厂方法中添加新的条件分支
  • 统一接口:所有计算图都实现了相同的接口,客户端可以统一处理

3.2 策略模式

虽然不是直接在 graph_imp.cpp 中实现,但整个计算图系统也体现了策略模式(Strategy Pattern):

  1. 上下文:使用计算图的客户端代码
  2. 策略接口Graph 类定义的接口
  3. 具体策略:不同的计算图实现(如 ChatGLMGraphGgmlLlamaGraph 等)

这种设计使得客户端可以在运行时选择不同的计算图实现,而不需要修改客户端代码。

4. 与其他组件的交互

graph_imp.cpp 文件通过工厂方法与框架的其他组件进行交互:

  1. 与模型实现的交互

    • 引入不同模型的头文件(chatGLM.hggml_llama.hllama_like.h
    • 创建不同模型的计算图实例
  2. 与设备的交互

    • 接收 Device* 参数,将设备传递给计算图实例
    • 计算图实例使用设备进行计算
  3. 与用户配置的交互

    • 接收 UserConfig 参数,将用户配置传递给计算图实例
    • 计算图实例根据用户配置调整行为

5. 扩展性分析

graph_imp.cpp 文件的设计具有良好的扩展性:

  1. 添加新模型
    要添加新的模型支持,只需:

    • 创建新的计算图类,继承自 Graph
    • make_graph 方法中添加新的条件分支
  2. 修改现有模型
    修改现有模型的实现不需要修改 graph_imp.cpp 文件,只需修改相应的计算图类。

总结

graph_imp.cpp 文件虽然简短,但在 InferLLM 框架中扮演着重要的角色,实现了计算图的工厂方法,使得框架可以支持多种不同的模型。它采用了工厂模式和策略模式的设计,具有良好的封装性和扩展性,为框架提供了灵活的模型支持机制。

通过这个文件,我们可以看到 InferLLM 框架的模块化设计思想,以及如何通过设计模式实现灵活的组件组合。这种设计使得框架可以方便地支持新的模型,而不需要大幅修改现有代码。