general-deep-learning / docs /architecture.md
yetrun's picture
ver3: 将源码迁入 src/deep_learning 包,重塑训练流水线,规范 data/model 契约
07cb7d3
|
Raw
History Blame Contribute Delete
9.48 kB

A newer version of the Gradio SDK is available: 6.22.0

Upgrade

项目架构说明

这份文档说明当前项目的代码结构,以及一次任务从入口脚本到训练、导出、样例测试的执行链路。重点说明四件事:

  • 数据从哪里来,如何变成训练数据
  • 模型在哪里构建,在哪里编译,如何转换成推理模型
  • 训练、导出、样例测试如何共用一套路径、日志和检查点规则
  • Gradio 展示如何复用导出的模型,而不参与训练抽象

总体分层

项目主要分成五层。

tasks

tasks/*/runner.py 是每个任务的命令入口。

它负责声明开发配置和生产配置,包括数据源、模型构建器、训练规则、生成规则和检查点加载规则。入口脚本本身不写训练循环,而是把配置好的 Pipeline 交给 PipelineRunner

典型结构是:

pipeline = resolve_env(
    SupervisedModelPipeline(...),
    SupervisedModelPipeline(...)
)

pipeline_runner = PipelineRunner(pipeline)

文本生成任务也遵循同样形状,只是 Pipeline 类型换成 TextGenerationPipeline

tasks/*/gradio.py 是展示入口。它通常加载已导出的模型或生成器,负责页面交互,不承担训练编排职责。

data

src/deep_learning/data 负责把原始数据变成 Pipeline 能消费的数据源。

当前对外契约集中在 src/deep_learning/data/spec/__init__.py

  • SupervisedDataSource:用于分类、分割、检测这类有监督任务,需要提供 training_ds()test_examples(model)
  • TextGenerationDataSource:用于文本生成任务,需要提供原始文档、token 数据、分词资源和数据配置
  • TokenizerBundle:文本推理时模型之外需要携带的分词器、解码函数、词表大小、结束标记等资源

这里的设计取向是让数据源自己说明训练数据怎么构建。比如 batch size、validation batches、sequence length 这类更贴近数据切分的配置,放在具体 DataSource 里,而不是塞进通用训练规则里。

models

src/deep_learning/models 负责模型构建、训练模型编译、推理模型转换和模型加载。

当前对外契约集中在 src/deep_learning/models/spec/__init__.py

  • SupervisedModelBuilder:负责构建有监督任务的训练模型、编译训练模型、转换或加载推理模型
  • TextGenerationModelBuilder:负责构建文本生成训练产物、编译模型、转换或加载文本推理产物
  • ModelArtifactTextGenerationModel:用统一对象承载模型产物

模型层不负责找数据、不负责写训练循环,也不负责 Gradio 页面。它只回答“这个任务的模型长什么样,怎么训练,怎么用于推理”。

pipeline

src/deep_learning/pipeline 是训练、导出和测试样例的统一编排层。

它负责:

  • 创建运行目录、日志目录、检查点目录和 TensorBoard 目录
  • 开启通用运行环境,例如 mixed precision
  • 写出配置日志
  • 加载或创建训练模型
  • 编译模型并组织 callbacks
  • 执行 Keras 训练
  • 按检查点导出完整模型
  • 从导出模型或训练检查点执行样例测试

PipelineRunner 暴露三个动作:

  • train
  • export
  • test

因此任务入口只需要声明一个 Pipeline,再交给 PipelineRunner。调用方不需要知道训练、导出和测试内部要走哪些目录和检查点规则。

ui

src/deep_learning/uitasks/*/gradio.py 负责展示层。

展示层的定位是“使用推理产物”,而不是“参与训练流程”。它可以复用数据集里的标签、分词器、样例展示能力,也可以复用 Pipeline 或模型构建器的加载能力,但不应该成为训练抽象的一部分。

两条主流程

当前项目主要有两条流程:有监督任务和文本生成任务。

有监督任务

有监督任务使用:

  • SupervisedDataSource
  • SupervisedModelBuilder
  • SupervisedModelPipeline

适用场景包括图片分类、语义分割,以及后续可以统一进来的其他监督学习任务。

训练链路是:

  1. tasks/*/runner.py 声明 SupervisedModelPipeline
  2. PipelineRunner.train() 调用 pipeline.train()
  3. Pipeline 创建运行目录,写配置日志
  4. Pipeline 从检查点恢复训练模型,或调用 model_builder.build_training_artifact() 创建新模型
  5. Pipeline 调用 model_builder.compile_training_model(model) 编译模型
  6. Pipeline 调用 data_source.training_ds() 得到训练集和验证集
  7. Pipeline 追加通用 callbacks,包括检查点和日志
  8. Pipeline 调用 model.fit(...)

导出链路是:

  1. PipelineRunner.export() 调用 pipeline.export_model()
  2. Pipeline 按导出规则加载训练检查点
  3. Pipeline 调用 model_builder.convert_to_inference_artifact(...)
  4. Pipeline 用 SaveKerasModelStage 保存完整 .keras 模型到 saved/models/<task_name>

样例测试链路是:

  1. PipelineRunner.test() 调用 pipeline.test_examples(checkpoint=...)
  2. 如果 checkpoint 是 test,Pipeline 从 saved/models/<task_name> 加载导出模型
  3. 如果 checkpoint 是 train,Pipeline 从训练检查点加载权重并转换推理模型
  4. Pipeline 调用 data_source.test_examples(model) 展示样例结果

文本生成任务

文本生成任务使用:

  • TextGenerationDataSource
  • TextGenerationModelBuilder
  • TextGenerationPipeline

适用场景包括诗词 GPT、Wiki GPT,以及字符级或 token 级文本生成任务。

训练链路是:

  1. tasks/*/runner.py 声明 TextGenerationPipeline
  2. PipelineRunner.train() 调用 pipeline.train()
  3. Pipeline 加载原始文档和 tokenizer 信息
  4. Pipeline 从 tokens_ds() 切出验证数据和训练数据
  5. Pipeline 从检查点恢复模型,或根据词表大小和序列长度创建新模型
  6. Pipeline 调用 model_builder.compile_training_model(model) 编译模型
  7. Pipeline 根据 GenerationRule 追加生成日志回调
  8. Pipeline 调用通用 KerasTrainStage 执行训练

导出链路是:

  1. Pipeline 准备文本数据和 tokenizer 资源
  2. Pipeline 按导出规则加载训练检查点
  3. Pipeline 调用 model_builder.convert_to_inference_artifact(...)
  4. Pipeline 保存完整推理模型

样例测试链路是:

  1. Pipeline 准备文本数据和 tokenizer 资源
  2. 如果 checkpoint 是 test,从导出模型加载推理产物
  3. 如果 checkpoint 是 train,从训练检查点加载训练产物并转换推理产物
  4. Pipeline 构建 TextGenerator
  5. Pipeline 使用 GenerationRule.prompts_generator 生成提示词,并打印生成结果

配置与产物

当前配置主要分为几类。

  • TrainingRule:训练轮数和每轮步数
  • GenerationRule:文本生成提示词来源和采样策略
  • CheckpointLoadRules:训练、导出、测试各自如何选择检查点
  • CheckpointConfig:检查点目录、具体路径、轮次和文件后缀

运行时目录由 build_runtime 统一生成,主要包括:

  • logs/<task_name>:配置日志和生成日志
  • checkpoints/<task_name>:训练过程中的权重检查点
  • saved/models/<task_name>:导出的完整模型

这样的划分让任务入口只声明“我想怎么跑”,Pipeline 统一处理“文件放哪里、检查点怎么找、导出怎么命名”。

历史结构与当前结构

上一版结构更强调通用阶段编排:

  • 一个通用 Pipeline 串联 runtime、data source、preprocess、model、compile、train、inference、export 等阶段
  • 每类任务通过 builder 装配 Pipeline,例如 image classification builder、segmentation builder、text builder、yolo builder
  • 任务目录里常见多个入口脚本,例如 train.pysave_model.pygenerate.py
  • 一些数据切分相关配置也放在训练规则中统一传递

这种设计的优点是阶段边界清楚,也更容易表达“所有任务都经过同一套通用流程”。但它的阅读成本更高:读者通常需要在任务入口、任务 builder、通用 Pipeline、各个 Stage、模型构建器和数据集之间多次跳转,才能理解一次训练具体发生了什么。

当前结构的设计取向是降低抽象层级,减少装配跳转,提升可读性和可改造性:

  • 任务入口统一为 tasks/*/runner.py
  • 入口脚本直接声明 DataSource、ModelBuilder 和 Pipeline
  • 有监督任务用 SupervisedModelPipeline 直接表达主流程
  • 文本任务保留必要的文本阶段对象,但主入口仍收敛到 TextGenerationPipeline
  • batch、validation、sequence length 等数据切分配置回到 DataSource
  • 模型构建、编译、训练产物和推理产物转换回到 ModelBuilder
  • PipelineRunner 统一暴露 trainexporttest

这不是在否定上一版设计。更准确地说,这是一次项目定位变化:从“抽象完整、阶段统一”,转向“入口更清楚、跳转更少、读者更容易改”。对于当前项目规模,读者能快速看懂数据、模型、训练和展示之间的关系,比保留更通用的阶段装配能力更重要。

当前边界

这个项目目前仍是小型 Keras 任务框架,不是完整生产级训练平台。

它适合:

  • 学习 Keras 任务如何从数据走到训练、导出和展示
  • 快速复制一个已有任务并改成自己的数据和模型
  • 在个人实验里保持统一目录、统一入口和统一检查点习惯