Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.22.0
项目架构说明
这份文档说明当前项目的代码结构,以及一次任务从入口脚本到训练、导出、样例测试的执行链路。重点说明四件事:
- 数据从哪里来,如何变成训练数据
- 模型在哪里构建,在哪里编译,如何转换成推理模型
- 训练、导出、样例测试如何共用一套路径、日志和检查点规则
- 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:负责构建文本生成训练产物、编译模型、转换或加载文本推理产物ModelArtifact和TextGenerationModel:用统一对象承载模型产物
模型层不负责找数据、不负责写训练循环,也不负责 Gradio 页面。它只回答“这个任务的模型长什么样,怎么训练,怎么用于推理”。
pipeline
src/deep_learning/pipeline 是训练、导出和测试样例的统一编排层。
它负责:
- 创建运行目录、日志目录、检查点目录和 TensorBoard 目录
- 开启通用运行环境,例如 mixed precision
- 写出配置日志
- 加载或创建训练模型
- 编译模型并组织 callbacks
- 执行 Keras 训练
- 按检查点导出完整模型
- 从导出模型或训练检查点执行样例测试
PipelineRunner 暴露三个动作:
trainexporttest
因此任务入口只需要声明一个 Pipeline,再交给 PipelineRunner。调用方不需要知道训练、导出和测试内部要走哪些目录和检查点规则。
ui
src/deep_learning/ui 和 tasks/*/gradio.py 负责展示层。
展示层的定位是“使用推理产物”,而不是“参与训练流程”。它可以复用数据集里的标签、分词器、样例展示能力,也可以复用 Pipeline 或模型构建器的加载能力,但不应该成为训练抽象的一部分。
两条主流程
当前项目主要有两条流程:有监督任务和文本生成任务。
有监督任务
有监督任务使用:
SupervisedDataSourceSupervisedModelBuilderSupervisedModelPipeline
适用场景包括图片分类、语义分割,以及后续可以统一进来的其他监督学习任务。
训练链路是:
tasks/*/runner.py声明SupervisedModelPipelinePipelineRunner.train()调用pipeline.train()- Pipeline 创建运行目录,写配置日志
- Pipeline 从检查点恢复训练模型,或调用
model_builder.build_training_artifact()创建新模型 - Pipeline 调用
model_builder.compile_training_model(model)编译模型 - Pipeline 调用
data_source.training_ds()得到训练集和验证集 - Pipeline 追加通用 callbacks,包括检查点和日志
- Pipeline 调用
model.fit(...)
导出链路是:
PipelineRunner.export()调用pipeline.export_model()- Pipeline 按导出规则加载训练检查点
- Pipeline 调用
model_builder.convert_to_inference_artifact(...) - Pipeline 用
SaveKerasModelStage保存完整.keras模型到saved/models/<task_name>
样例测试链路是:
PipelineRunner.test()调用pipeline.test_examples(checkpoint=...)- 如果 checkpoint 是
test,Pipeline 从saved/models/<task_name>加载导出模型 - 如果 checkpoint 是
train,Pipeline 从训练检查点加载权重并转换推理模型 - Pipeline 调用
data_source.test_examples(model)展示样例结果
文本生成任务
文本生成任务使用:
TextGenerationDataSourceTextGenerationModelBuilderTextGenerationPipeline
适用场景包括诗词 GPT、Wiki GPT,以及字符级或 token 级文本生成任务。
训练链路是:
tasks/*/runner.py声明TextGenerationPipelinePipelineRunner.train()调用pipeline.train()- Pipeline 加载原始文档和 tokenizer 信息
- Pipeline 从
tokens_ds()切出验证数据和训练数据 - Pipeline 从检查点恢复模型,或根据词表大小和序列长度创建新模型
- Pipeline 调用
model_builder.compile_training_model(model)编译模型 - Pipeline 根据
GenerationRule追加生成日志回调 - Pipeline 调用通用
KerasTrainStage执行训练
导出链路是:
- Pipeline 准备文本数据和 tokenizer 资源
- Pipeline 按导出规则加载训练检查点
- Pipeline 调用
model_builder.convert_to_inference_artifact(...) - Pipeline 保存完整推理模型
样例测试链路是:
- Pipeline 准备文本数据和 tokenizer 资源
- 如果 checkpoint 是
test,从导出模型加载推理产物 - 如果 checkpoint 是
train,从训练检查点加载训练产物并转换推理产物 - Pipeline 构建
TextGenerator - 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.py、save_model.py、generate.py - 一些数据切分相关配置也放在训练规则中统一传递
这种设计的优点是阶段边界清楚,也更容易表达“所有任务都经过同一套通用流程”。但它的阅读成本更高:读者通常需要在任务入口、任务 builder、通用 Pipeline、各个 Stage、模型构建器和数据集之间多次跳转,才能理解一次训练具体发生了什么。
当前结构的设计取向是降低抽象层级,减少装配跳转,提升可读性和可改造性:
- 任务入口统一为
tasks/*/runner.py - 入口脚本直接声明 DataSource、ModelBuilder 和 Pipeline
- 有监督任务用
SupervisedModelPipeline直接表达主流程 - 文本任务保留必要的文本阶段对象,但主入口仍收敛到
TextGenerationPipeline - batch、validation、sequence length 等数据切分配置回到 DataSource
- 模型构建、编译、训练产物和推理产物转换回到 ModelBuilder
PipelineRunner统一暴露train、export、test
这不是在否定上一版设计。更准确地说,这是一次项目定位变化:从“抽象完整、阶段统一”,转向“入口更清楚、跳转更少、读者更容易改”。对于当前项目规模,读者能快速看懂数据、模型、训练和展示之间的关系,比保留更通用的阶段装配能力更重要。
当前边界
这个项目目前仍是小型 Keras 任务框架,不是完整生产级训练平台。
它适合:
- 学习 Keras 任务如何从数据走到训练、导出和展示
- 快速复制一个已有任务并改成自己的数据和模型
- 在个人实验里保持统一目录、统一入口和统一检查点习惯