├── .github └── workflows │ ├── main.yml │ └── update_docs.yml ├── .gitignore ├── README.md ├── appendix_machine_learning_introduction ├── classic_machine_learning.md ├── gradient_descent.md ├── index.md └── neural_network.md ├── build_and_transform.sh ├── build_html.sh ├── chapter_accelerator ├── accelerator_architecture.md ├── accelerator_introduction.md ├── accelerator_practise.md ├── accelerator_programming.md ├── index.md └── summary.md ├── chapter_backend_and_runtime ├── compute_schedule_and_execute.md ├── graph_optimizer.md ├── index.md ├── kernel_selecter.md ├── memory_allocator.md ├── op_compiler.md ├── overview.md └── summary.md ├── chapter_computational_graph ├── background_and_functionality.md ├── components_of_computational_graph.md ├── generation_of_computational_graph.md ├── index.md ├── schedule_of_computational_graph.md └── summary.md ├── chapter_data_processing ├── data_order.md ├── extension.md ├── index.md ├── performance.md ├── program_model.md ├── requirements.md └── summary.md ├── chapter_distributed_training ├── cluster.md ├── collective.md ├── index.md ├── methods.md ├── overview.md ├── parameter_servers.md └── summary.md ├── chapter_explainable_AI ├── explainable_ai.md └── index.md ├── chapter_federated_learning ├── horizontal_fl.md ├── index.md ├── outlook.md ├── overview.md ├── privacy_encryption_algorithm.md ├── summary.md └── vertical_fl.md ├── chapter_frontend_and_ir ├── ad.md ├── ai_compiler_design_principle.md ├── common_frontend_optimization_pass.md ├── index.md ├── intermediate_representation.md ├── overview_of_frontend.md ├── summary.md └── type_system_and_static_analysis.md ├── chapter_introduction ├── applications.md ├── architecture.md ├── design.md ├── ecosystem.md ├── index.md └── readers.md ├── chapter_model_deployment ├── index.md ├── model_compression.md ├── model_converter_and_optimizer.md ├── model_deployment_introduction.md ├── model_inference.md ├── model_security.md └── summary.md ├── chapter_preface └── index.md ├── chapter_preface_advanced └── index.md ├── chapter_preface_extension └── index.md ├── chapter_programming_interface ├── c_python_interaction.md ├── development_history.md ├── index.md ├── ml_programming_paradigm.md ├── ml_workflow.md ├── neural_network_layer.md └── summary.md ├── chapter_recommender_system ├── case_study.md ├── index.md ├── model_update.md ├── multi_stage_recommender_system.md ├── summary.md └── system_architecture.md ├── chapter_reinforcement_learning ├── distributed_node_rl.md ├── index.md ├── marl.md ├── marl_sys.md ├── rl_introduction.md ├── single_node_rl.md └── summary.md ├── chapter_rl_sys ├── control.md ├── control_code_ex.md ├── index.md ├── perception.md ├── perception_code_ex.md ├── planning.md ├── planning_code_ex.md ├── rl_sys_intro.md ├── robot_learning.md ├── robot_safety.md ├── ros.md ├── ros_code_ex.md └── summary.md ├── config.ini ├── img ├── Advanced │ ├── preface3_1.png │ ├── preface3_2.png │ ├── preface3_3.png │ ├── preface3_4.png │ ├── preface3_5.png │ └── preface3_arc.png ├── ch01 │ ├── framework-architecture.png │ └── system-ecosystem.png ├── ch02 │ ├── cell_abstract.svg │ ├── channels_conv.svg │ ├── conv_component.svg │ ├── fc_layer_1.svg │ ├── framework_development_history.svg │ ├── img_workflow.svg │ ├── model_build.svg │ ├── nn_network.svg │ ├── pooling.svg │ └── single_channel_conv.svg ├── ch03 │ ├── ast.svg │ ├── ast1.svg │ ├── asyn_para.svg │ ├── asynchronous.svg │ ├── chain.png │ ├── chain.svg │ ├── dag.svg │ ├── dependence.svg │ ├── dynamic-gen.svg │ ├── dynamic-gen1.svg │ ├── dynamic.svg │ ├── dynamic1.svg │ ├── dynamic_gen.png │ ├── eager-gen.png │ ├── eager.png │ ├── graph.png │ ├── if.png │ ├── if.svg │ ├── order.png │ ├── order.svg │ ├── para.svg │ ├── recurrent.png │ ├── recurrent.svg │ ├── schedule.svg │ ├── simpledag.png │ ├── simpledag.svg │ ├── static-gen.svg │ ├── static.png │ ├── static.svg │ ├── static1.svg │ ├── static_gen.png │ ├── synchronization.svg │ ├── tensor.png │ ├── tensor.svg │ ├── tensorclass.svg │ ├── unroll.png │ ├── unroll.svg │ ├── while.png │ └── while.svg ├── ch04 │ ├── LLVM基础结构.png │ ├── TensorFlow-IR.png │ ├── 中间表示-ASTDAG.svg │ ├── 中间表示-Jaxpr.png │ ├── 中间表示-LLVMIR.png │ ├── 中间表示-MLIR.png │ ├── 中间表示-MindIR.png │ ├── 中间表示-MindIR图.png │ ├── 中间表示-MindIR示例.png │ ├── 中间表示-torchscript.png │ ├── 中间表示-中间表示结构.png │ ├── 中间表示-线性中间表示.png │ ├── 符号微分的表达式膨胀问题.png │ ├── 编译优化-pass结构.svg │ ├── 编译优化-公共子表达式消除.svg │ ├── 编译优化-常量传播与常量折叠.svg │ ├── 编译优化-无用代码消除.svg │ ├── 编译器前端基础架构.svg │ ├── 编译器整体流程.png │ ├── 自动微分-前向模式自动微分示例.png │ ├── 自动微分-反向模式自动微分示例.png │ ├── 自动微分-示例计算图.svg │ └── 静态分析-静态分析模块.png ├── ch05 │ ├── SIMD.png │ ├── SIMT.png │ ├── combine_memory_reuse_and_no_reuse.png │ ├── compiler-backend-architecture.png │ ├── computation_graph.png │ ├── concat.png │ ├── conv_sum_relu.png │ ├── data_format.png │ ├── device_malloc.png │ ├── floatdtype.png │ ├── graph_exec.png │ ├── graph_exec_1.png │ ├── graph_exec_2.png │ ├── graph_exec_3.png │ ├── graph_exec_4.png │ ├── graph_exec_5.png │ ├── graph_exec_6.png │ ├── graph_exec_7.png │ ├── graph_exec_8.png │ ├── graph_kernel.png │ ├── host-device-memory.png │ ├── inplace-op.png │ ├── matmuldatalayout.png │ ├── memory_allocate.png │ ├── memory_architecture.png │ ├── memory_fusion.png │ ├── nchw.png │ ├── nchwandnhwc.png │ ├── parallel_computing.png │ ├── poly.png │ ├── poly_test.png │ ├── select_kernel.png │ ├── side_effect_1.png │ ├── side_effect_2.png │ ├── single_op_exec.PNG │ └── transdata.png ├── ch06 │ ├── 6.4 │ │ ├── duplicated_data.png │ │ ├── hide_global_latency.png │ │ ├── hide_smem_latency.png │ │ ├── naive.png │ │ ├── use_float4.png │ │ ├── use_smem_load.png │ │ ├── use_smem_pipeline.png │ │ ├── use_smem_store.png │ │ └── use_tile.png │ ├── G2S.svg │ ├── MLIR-Lowing.svg │ ├── MLIR-Lowing_cn.png │ ├── R2TC.svg │ ├── S2R.svg │ ├── SM.svg │ ├── SM_cn.png │ ├── TBE.svg │ ├── TBE_cn.png │ ├── TVM.svg │ ├── TVM_cn.png │ ├── V100.svg │ ├── V100_cn.png │ ├── akg.png │ ├── akg_cn.png │ ├── compute_unit.svg │ ├── compute_unit_cn.png │ ├── davinci_architecture.svg │ ├── gemm.svg │ ├── gemm_tensor_core.svg │ ├── ptx.svg │ └── tensor_core.svg ├── ch07 │ ├── 7.1 │ │ └── pipeline.png │ ├── 7.2 │ │ ├── RDD.png │ │ ├── dataset-plugin.png │ │ ├── dataset.png │ │ ├── dataset_table.png │ │ ├── image_process_pipeline.png │ │ └── operation.png │ ├── 7.3 │ │ ├── MindRecord_format.png │ │ ├── async_data_process.png │ │ ├── file_indexing.png │ │ ├── map_reduce.png │ │ ├── operator_parallisim.png │ │ ├── partition.png │ │ ├── pipeline_parallisim.png │ │ ├── pytorch_dataloader.png │ │ ├── single_pipeline.png │ │ └── uni_record.png │ ├── 7.4 │ │ ├── data_ordering.png │ │ └── mindspore_data_order.jpeg │ └── 7.5 │ │ ├── dali_overview.png │ │ └── distribute.png ├── ch08 │ ├── AttentionTS.png │ ├── bn-replace.png │ ├── conv-bn-fusion.png │ ├── conv_2d.png │ ├── conv_nhwc.png │ ├── crop-reorder.png │ ├── deepcomp.png │ ├── distillation.png │ ├── flow.png │ ├── fmla.png │ ├── gemm.png │ ├── img2col_input.png │ ├── img2col_weight.png │ ├── model_obfuscate.png │ ├── parallel.png │ ├── quant-minmax-outpoints.png │ ├── quant-minmax.png │ ├── register.png │ ├── storage.png │ └── winograd.png ├── ch09 │ ├── ch10-allreduce-process.png │ ├── ch10-allreduce-process.svg │ ├── ch10-allreduce-state.png │ ├── ch10-allreduce-state.svg │ ├── ch10-averaged-gradient.svg │ ├── ch10-collective-operators.png │ ├── ch10-computation-increase.png │ ├── ch10-computation-increase.svg │ ├── ch10-data-parallel.png │ ├── ch10-data-parallel.svg │ ├── ch10-datacentre.png │ ├── ch10-datacentre.svg │ ├── ch10-hybrid-parallel.png │ ├── ch10-hybrid-parallel.svg │ ├── ch10-model-parallel-inter-op.png │ ├── ch10-model-parallel-inter-op.svg │ ├── ch10-model-parallel-intra-op.png │ ├── ch10-parameter-server-replication.svg │ ├── ch10-parameter-servers.png │ ├── ch10-parameter-servers.svg │ ├── ch10-pipeline-parallel.png │ ├── ch10-pipeline-parallel.svg │ ├── ch10-recommendation-model.svg │ ├── ch10-redistribution.pdf │ ├── ch10-redistribution.png │ ├── ch10-single-node.png │ ├── ch10-single-node.svg │ ├── ch10-single-vs-multi.png │ └── ch10-single-vs-multi.svg ├── ch10 │ ├── ch-recsys │ │ ├── ch10-recommendation-models.png │ │ ├── ch10-recommendation-systems.png │ │ ├── chain_replication.png │ │ ├── content_embedding_missing.png │ │ ├── dlrm_model.png │ │ ├── ekko_overview.png │ │ ├── feature_store.png │ │ ├── interaction.png │ │ ├── offline_update.png │ │ ├── online_update.png │ │ ├── p2p_replication.png │ │ ├── parameter_server_in_recommendation.png │ │ ├── recommender_pipeline.png │ │ ├── state_manager.png │ │ ├── system_challenges.png │ │ ├── two_tower_model.png │ │ ├── update_scheduler.png │ │ └── user_embedding_missing.png │ ├── ch10-abstract-recommendation-systems.png │ ├── ch10-abstract-recommendation-systems.svg │ ├── ch10-federated-learning-architecture.svg │ ├── ch10-federated-learning-different-connection.png │ ├── ch10-federated-learning-fedavg.png │ ├── ch10-federated-learning-flow.png │ ├── ch10-federated-learning-signds.PNG │ ├── ch10-federated-learning-vfl-arch.svg │ ├── ch10-federated-learning-vfl-data.png │ ├── ch10-federated-learning-vfl-train.svg │ ├── ch10-recommendation-models.png │ ├── ch10-recommendation-models.svg │ ├── ch10-recommendation-systems.png │ └── ch10-recommendation-systems.svg ├── ch11 │ ├── XAI_methods.PNG │ ├── correct_correct.png │ ├── correct_wrong.png │ ├── mindspore_xai.png │ ├── tabular.png │ ├── tabular_shap.png │ ├── tb_net.png │ ├── tbnet_finance.png │ ├── wrong_wrong.png │ ├── xai_concept.png │ ├── xai_concept_en.PNG │ ├── xai_data_driven.png │ ├── xai_global_feature_importance.png │ ├── xai_gradient_based.PNG │ ├── xai_kg_recommendation.png │ ├── xai_lime.png │ └── xai_tcav.png ├── ch12 │ ├── ch12-a3c.pdf │ ├── ch12-a3c.png │ ├── ch12-impala.pdf │ ├── ch12-impala.png │ ├── ch12-marl-fsp.pdf │ ├── ch12-marl-fsp.png │ ├── ch12-marl-sp.pdf │ ├── ch12-marl-sp.png │ ├── ch12-marl-sys.png │ ├── ch12-marl-sys.svg │ ├── ch12-marl-train.pdf │ ├── ch12-marl-train.png │ ├── ch12-marl-train.svg │ ├── ch12-marl.pdf │ ├── ch12-marl.png │ ├── ch12-rl.pdf │ ├── ch12-rl.png │ ├── ch12-rllib-arch.png │ ├── ch12-rllib-arch.svg │ ├── ch12-rllib-distributed.png │ ├── ch12-rllib-distributed.svg │ ├── ch12-rlzoo.pdf │ └── ch12-rlzoo.png ├── ch13 │ ├── ROS2_arch.png │ ├── affordance.png │ ├── idm.png │ ├── orbslam3.png │ ├── real-world.png │ ├── rl_ad.png │ ├── robot_learning_overview.png │ ├── ros-apple.jpg │ ├── ros-pineapple.jpg │ ├── ros2-gazebo-1.JPG │ ├── ros2-rviz-1.JPG │ ├── ros2-rviz-2.JPG │ ├── ros2_actions.png │ ├── ros2_graph.png │ ├── ros2_services.png │ ├── ros2_topics.png │ ├── safe_learning_control.png │ ├── simulator.png │ └── vehicle_computing.png ├── ch_basic │ ├── conv_computation_v4.png │ ├── gradient_descent2.png │ ├── mlp2.png │ ├── pooling_v3.png │ ├── rnn_simple_cell2.png │ ├── single_neuron2.png │ ├── single_neuron_bias2.png │ ├── single_neuron_decision_boundary2.png │ └── two_neurons2.png └── guide │ ├── step1.png │ ├── step2.png │ ├── step3.png │ ├── step4.png │ ├── step5.png │ └── step6.png ├── index.md ├── info ├── Pic-Instruction │ ├── Pic_Templates_and_Samples.pptx │ └── Requirements and Instructions.md ├── editors.md ├── info.md ├── issue.md ├── mlsys_group.png ├── refenence_guide.md ├── style.md └── terminology.md ├── mlsys.bib ├── references ├── accelerator.bib ├── appendix.bib ├── backend.bib ├── data.bib ├── explainable.bib ├── extension.bib ├── federated.bib ├── frontend.bib ├── graph.bib ├── interface.bib ├── introduction.bib ├── model.bib ├── model_deployment.bib ├── recommender.bib ├── reinforcement.bib ├── rlsys.bib └── training.bib ├── requirements.txt ├── static ├── favicon.png ├── frontpage.html ├── image │ ├── guozhijian.png │ ├── jinxuefeng.png │ ├── logo.png │ ├── wanghanchen.png │ ├── wutiancheng.png │ ├── zhaizhiqiang.png │ ├── zhangqinghua.png │ └── zhangrenwei.png ├── logo-with-text.png ├── logo.png └── readme.md └── tools ├── contribution_analysis.py └── format_tables.py /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | - push 5 | - pull_request 6 | - workflow_dispatch # Allows you to run this workflow manually from the Actions tab 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-20.04 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | - uses: s-weigand/setup-conda@v1 15 | - name: Set up Python 3.8 16 | uses: actions/setup-python@v3 17 | with: 18 | python-version: '3.8' 19 | - run: conda config --append channels conda-forge 20 | - run: python3 -m pip install -r requirements.txt 21 | - run: conda install -y pandoc==2.17 22 | 23 | - run: | 24 | git clone https://github.com/openmlsys/d2l-book.git 25 | cd d2l-book 26 | python3 -m pip install . 27 | - run: d2lbook build html 28 | -------------------------------------------------------------------------------- /.github/workflows/update_docs.yml: -------------------------------------------------------------------------------- 1 | 2 | name: CI 3 | 4 | on: 5 | pull_request: 6 | types: 7 | - closed 8 | 9 | jobs: 10 | if_merged: 11 | if: github.event.pull_request.merged == true 12 | runs-on: ubuntu-20.04 13 | steps: 14 | - uses: actions/checkout@v2 15 | - uses: s-weigand/setup-conda@v1 16 | - run: conda config --append channels conda-forge 17 | - run: python3 -m pip install -r requirements.txt 18 | - run: conda install -y pandoc==2.17 19 | - run: pip install sphinx-mathjax-offline 20 | 21 | - run: | 22 | git clone https://github.com/openmlsys/d2l-book.git 23 | cd d2l-book 24 | python3 -m pip install . 25 | - run: sh build_html.sh 26 | - run: cd .. 27 | - run: git clone https://github.com/openmlsys/openmlsys.github.io.git 28 | - run: cp -r openmlsys-zh/_build/html/* openmlsys.github.io/docs/ 29 | - run: | 30 | cd openmlsys.github.io 31 | git add . 32 | git commit -m 'update docs' 33 | git push 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.ipynb_checkpoints 2 | **/__pycache__ 3 | data/ 4 | *.json 5 | *.params 6 | *.DS_Store 7 | *.csv 8 | *egg-info* 9 | dist* 10 | _build/ 11 | test*.md 12 | run.sh 13 | .idea 14 | env 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 机器学习系统:设计和实现 2 | 3 | 本开源项目试图给读者讲解现代机器学习系统的设计原理和实现经验。 4 | 5 | 🔥 **书籍网页版:** [机器学习系统:设计和实现](https://openmlsys.github.io/) 6 | 7 | 🔥 **书籍PDF:** 将在勘误后,2022年中发布。 8 | 9 | ## 发布 10 | 11 | - 27/06/2022: OpenMLSys社区发布通俗易懂的高性能AI算子开发教程,助力学生和工程师60分钟理解算子性能优化的关键知识点。相应的[技术博客](https://zhuanlan.zhihu.com/p/531498210)和[复现代码](https://github.com/openmlsys/openmlsys-cuda)都已免费公开。感谢@[Jie Ren](https://github.com/JieRen98) 和 @[Wenteng Liang](https://github.com/Went-Liang) 的贡献!🔥 12 | - 17/03/2022: 本书处于勘误阶段。如发现文字和图片错误,可创建Issue并@[章节编辑](info/editors.md)。我们非常欢迎社区提交PR直接勘误。 13 | 14 | ## 适用读者 15 | 16 | 本书的常见读者包括: 17 | 18 | - **学生:** 19 | 随着大量机器学习课程在大学中的普及,学生已经开始掌握大量机器学习的基础理论和神经网络的实现。然而,需要训练出可以实际应用的机器学习模型,需要对现代机器学习系统有充分的认识。 20 | 21 | - **科研人员:** 22 | 研发新型的机器学习模型不仅仅需要会使用基础的机器学习系统接口。同时,新型的模型需要给系统提供新的自定义算子(Custom 23 | Operators),又或者是会利用高级的分布式执行算子来实现大模型的开发。这一系列需求都需要对底层系统具有充分认识。 24 | 25 | - **开发人员:** 26 | 大量的数据和AI驱动的公司都部署了机器学习基础设施。这一设施的核心就是机器学习系统。因此了解机器学习系统有助于开发人员对于系统性能调优,以定位问题,并且根据业务需求对机器学习系统进行深度定制。 27 | 28 | ## 内容介绍 29 | 30 | 现代机器学习框架具有复杂的内部架构和繁多的外部相关组件。在本书中,我们将对其细致拆分,深入解读: 31 | 32 | 基础: 33 | 34 | - **编程接口:** 为了支持海量应用,机器学习框架的编程接口设计具有大量的设计哲学,在易用性和性能之间取得平衡。本书将讲述编程接口的演进,机器学习工作流,定义深度学习模型,以及用C/C++进行框架开发。 35 | 36 | - **计算图:** 机器学习框架需要支持自动微分,硬件加速器,多编程前端等。实现这些支持的核心技术是:计算图(Computational Graph)。本书将讲述计算图的基本构成,生成方法和调度策略。 37 | 38 | 性能进阶: 39 | 40 | - **编译器前端:** 41 | 机器学习框架需要利用编译器前端技术对计算图进行功能拓展和性能优化。本书将讲述常见的前端技术,包括类型推导,中间表示(Intermediate Representation),自动微分等。 42 | 43 | - **编译器后端和运行时:** 44 | 机器学习框架的一个核心目标是:如何充分利用异构硬件。这其中会涉及编译器后端技术,以及将计算图算子(Operator)调度到硬件上的运行时(Runtime)。本书将讲述计算图优化,算子选择,内存分配和计算调度与执行。 45 | 46 | - **硬件加速器:** 47 | 机器学习框架的基本运行单元是算子,而算子的实现必须充分利用硬件加速器(GPU和Ascend)的特性。本书将会讲述硬件加速器的基本构成原理和常见的高性能编程接口。 48 | 49 | - **数据处理框架:** 50 | 机器学习框架会集成高性能框架来进行数据预处理。本书将会讲述这一类数据处理框架在设计中需要达到的多个目标:易用性,高效性,保序性,分布式等。 51 | 52 | - **模型部署:** 53 | 在模型完成训练后,用户需要将模型部署到终端设备(如云服务器,移动终端和无人车)。这其中涉及到的模型转换,模型压缩,模型推理和安全保护等知识也会在本书中讨论。 54 | 55 | - **分布式训练:** 56 | 机器学习模型的训练需要消耗大量资源。越来越多的机器学习框架因此原生支持分布式训练。在本书中我们将会讨论常见的分布式训练方法(包括数据并行,模型并行和流水线并行),以及实现这些方法的系统架构(包括集合通讯和参数服务器)。 57 | 58 | 功能拓展: 59 | 60 | - **深度学习推荐系统:** 推荐系统是目前机器学习应用最成功的领域之一。本书将会概括推荐系统的运作原理,详细描述大规模工业场景下的推荐系统架构设计。 61 | 62 | - **联邦学习系统:** 随着数据保护法规和隐私保护的崛起,联邦学习正成为日益重要的研究领域。本书将会介绍联邦学习的常用方法以及相关系统实现。 63 | 64 | - **强化学习系统:** 强化学习是走向通用人工智能的关键技术。本书将会介绍目前常见的强化学习系统(包括单智能体和多智能体等)。 65 | 66 | - **可解释性AI系统:** 随着机器学习在安全攸关(Safety-critical)领域的应用,机器学习系统越来越需要对决策给出充分解释。本书将会讨论可解释AI系统的常用方法和落地实践经验。 67 | 68 | - **机器人系统:** 机器人(无人车,无人机,家用机器人等)作为机器学习技术重要的应用领域,在最近数年得到了广泛应用。在实践中,机器人系统在实时性,安全性,鲁棒性等方面都有极高要求,这要求开发者具有算法和系统的双重思维,从而解决实际问题。本书中我们将结合最新研究成果和机器人系统实践经验讲解该类系统的设计原则和实现细节。 69 | 70 | 71 | 我们在持续拓展拓展本书的内容,如元学习系统,自动并行,深度学习集群调度,绿色AI系统,图学习系统等。我们也非常欢迎社区对于新内容提出建议,贡献章节。 72 | 73 | ## 构建指南 74 | 75 | 请参考[构建指南](info/info.md)来了解如何构建本书的网页版本和PDF版本。 76 | 77 | ## 写作指南 78 | 79 | 我们欢迎大家来一起贡献和更新本书的内容。常见的贡献方式是提交PR来更新和添加Markdown文件。写作的风格和图片要求请参考[风格指南](info/style.md)。同时,机器学习领域涉及到大量的中英文翻译,相关的翻译要求请参考[术语指南](info/terminology.md)。 80 | -------------------------------------------------------------------------------- /appendix_machine_learning_introduction/classic_machine_learning.md: -------------------------------------------------------------------------------- 1 | ## 经典机器学习方法 2 | 3 | 大量经典机器学习算法,如 支持向量机(Support Vector Machine,SVM), 4 | K最近邻(K-Nearest Neighbor, KNN)分类算法 和K均值聚类算法(K-Means 5 | Clustering Algorithm)等, 6 | 虽然它们有的有网络参数,有的没有网络参数,有的是监督学习算法,有的是无监督学习算法, 7 | 训练过程也不一样,但是从系统的角度,它们都是以矩阵运算为基础的。下面,我们来简要介绍一下这些算法。 8 | 9 | ### 支持向量机 10 | 11 | **支持向量机**(Support Vector 12 | Machine,SVM),是一种经典的机器学习分类算法,其核心思想在于最大化决策边界到数据点的距离。在这里,我们以线性可分数据为例;对于非线性可分的数据,运用**核方法**(Kernel 13 | Method)即可类似处理。 14 | 15 | 如果训练数据是线性可分的,SVM的目标则是最大化**间隔**(Margin)。首先,我们先来定义最大化间隔的分类器,如下: 16 | $$\min_{{w},b} ~~~\frac{1}{2} ||{w}||^2$$ 17 | $$s.t. ~~~y_i ({w}^T {x_i} + b) \geq 1, ~~~\forall 1 \leq i \leq n$$ 18 | 其拉格朗日乘子为 19 | $$L({w},b,{\lambda}) = \frac{1}{2} ||{w}||^2 + \sum_{i=1}^n \lambda_i (1-y_i({w}^T {x_i} + b))$$ 20 | 由于$\frac{1}{2} ||{w}||^2$是凸的,并且$\lambda_i (1-y_i({w}^T {x_i} + b))$是线性的(也是凸的),所以优化问题的解为 21 | $$\max_{\lambda>0} \min_{{w},b} L({w},b, {\lambda})$$ 22 | 求$L$关于${w},b$的导数有 23 | $$\nabla_{{w}} L= {w} - \sum_{i=1}^n \lambda_i y_i {x_i}$$ 24 | $$\nabla_b L = - \sum_{i=1}^n \lambda_i y_i$$ 25 | 令$L$关于${w},b$的导数均为0得到,${w}^* = \sum_{i=1}^n \lambda_i y_i {x_i}$以及$\sum_{i=1}^n \lambda_i y_i = 0$。 26 | 由于当$\lambda$固定的时候,$b$的值对目标函数无贡献,所以可以令$b^* = 0$。 27 | 这时,由对偶性理论和KTT条件,我们得到: 28 | $$y_i ({w}^{*T} {x_i} + b^*) > 1 \Rightarrow \lambda_i^* = 0$$ 29 | $$\lambda_i^* > 0 \Rightarrow y_i ({w}^{*T} {x_i} + b^*) = 1$$ 30 | $${w}^* = \sum_{i=1}^n \lambda_i^* y_i {x_i}$$ 31 | 如果$y_i ({w}^{*T} {x_i} + b^*) = 1$,那么${x_i}$就是离超平面$({w}^*,b^*)$最近的点之一,否则就不是。因此,${w}^*$就是离超平面$({w}^*,b^*)$最近的点${x_i}$的线性组合。 32 | 33 | 如此,通过SVM算法,我们实现了数据的分类,并且能够最大化了决策边界到最近点的距离。 34 | 我们定义满足$y_i ({w}^{*T} {x_i} + b^*) = 1$的${x_i}$为**支持向量**(Support 35 | Vectors),同时把分类器$\hat{y}=sgn({w}^{*T} {x_i} + b^*)$称为支持向量机。 36 | 37 | ### K最近邻算法 38 | 39 | **K最近邻算法**(K-Nearest 40 | Neighbor,KNN)也是一种传统的机器学习算法,可用于分类、回归等基本的机器学习任务。和上面介绍的SVM算法不同,K最近邻算法的核心思想并不是用一个决策边界把属于不同类的数据分开,而是依靠每个数据点周围几个距离最近的数据的性质,来预测数据点本身的性质。 41 | 42 | KNN用于分类时,为了预测某个样本点的类别,会进行一次投票。投票的对象为离这个观测样本点最近的K个样本点,每个要投票的样本点可能会被赋予不同的权重,而投票的"内容"则是样本点的类别。处理投票结果的时候,采用的是少数服从多数的决策方法(Majority 43 | Vote)。也就是说,若一个样本点最近的K个样本点中大多数属于某个类别,那么该样本点也属于这个类别。 44 | 45 | KNN算法的具体描述如下:(1)计算待分类点到各已知类别点的距离;(2)将这些点按照距离排序,并按照距离挑选出最近的K个点;(3)按照每个点的权重进行"统票",票面内容为点所处的类别;(4)返回得票最高的类别,并作为待分类点的预测类别。 46 | 47 | KNN算法有几个需要注意的关键问题,包括超参数K的选择,距离的度量方式,还有分类决策规则。对于超参数K,不宜过大,否则会导致很大的近似误差,反之亦不宜过小,否则会导致很大的估计误差。距离的度量,则可以选择曼哈顿距离、欧式距离和闵可夫斯基距离等等。为了降低K值对于预测结果产生的误差和影响,我们通常可以对分类决策规则做一定的规定,比如在投票决策时让距离小的点有更大的权重,距离较大的点权重较小。在编程实现KNN算法的时候,权重等参数都会以矩阵的形式进行运算,以提高运算效率。 48 | 49 | ### K均值聚类算法 50 | 51 | **K均值聚类算法**(K-Means Clustering 52 | Algorithm)是机器学习中一种常见的无监督聚类算法。在这里,我们首先定义聚类问题:给定数据点${x_1},\cdots, {x_n} \in \mathbb{R}^d$和$K\in \mathbb{N}$,需要划分为$K$个簇${C_1}, \cdots, {C_K} \in \mathbb{R}^d$以及每个数据点所对应的分类中心点${ C_{(1)}}, \cdots, {C_{(n)}}$,以最小化距离和$\sum_i ||{x_i} - {C_{(i)}}||^2$。 53 | 54 | K均值聚类算法是一种解决聚类问题的算法,算法过程如下: 55 | 56 | - 随机选择${C_1}, \cdots, {C_K}$ 57 | 58 | - 把${x_i}$所对应的分类置为距离其最近的聚类中心点的分类 59 | 60 | - 计算并赋值${C_K} = \frac{\sum_{{C_{(i)}}={C_K}} {x_i}}{\sum_{{C_{(i)}}={C_K}} 1}$ 61 | 62 | - 重复以上步骤直到算法收敛 63 | 64 | 可以证明,K均值聚类算法会使得距离和$\sum_i ||{x_i} - {C_{(i)}}||^2$不断地单调减小,并且最终能够收敛。不过,算法可能收敛到局部最小值。 65 | 66 | 本章结束语: 67 | 68 | 在系统角度,机器学习的算法无论是什么算法,涉及到高维数据任务的现都是矩阵运算实现的。 69 | 70 | ## 参考文献 71 | 72 | :bibliography:`../references/appendix.bib` -------------------------------------------------------------------------------- /appendix_machine_learning_introduction/index.md: -------------------------------------------------------------------------------- 1 | # 附录:机器学习介绍 2 | 3 | 本书假设读者有一定的机器学习算法基础,因此本章只会简略地介绍一下机器学习,其中的梯度下降方法对本书机器学习系统来说尤为重要,是必须掌握的内容。 4 | 5 | ```toc 6 | :maxdepth: 2 7 | :numbered: 8 | 9 | neural_network 10 | gradient_descent 11 | classic_machine_learning 12 | ``` -------------------------------------------------------------------------------- /build_and_transform.sh: -------------------------------------------------------------------------------- 1 | d2lbook build html 2 | python3 tools/format_tables.py -------------------------------------------------------------------------------- /build_html.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | rm -rf _build/rst _build/html 6 | d2lbook build rst 7 | cp static/frontpage.html _build/rst/ 8 | d2lbook build html 9 | cp -r static/image/* _build/html/_images/ 10 | python3 tools/format_tables.py -------------------------------------------------------------------------------- /chapter_accelerator/accelerator_introduction.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | ### 硬件加速器设计的意义 4 | 5 | 未来人工智能发展的三大核心要素是数据、算法和算力。目前,人工智能系统算力大都构建在CPU和GPU之上且主体多是GPU。随着神经网络的层增多,模型体量增大,算法趋于复杂,CPU和GPU很难再满足新型网络对于算力的需求。例如,2015年谷歌的AlphaGo用了1202个CPU和176个GPU打败了人类职业选手,每盘棋需要消耗上千美元的电费,而与之对应的是人类选手的功耗仅为20瓦。 6 | 7 | 虽然GPU在面向向量、矩阵以及张量的计算上,引入许多新颖的优化设计,但由于GPU需要支持的计算类型复杂,芯片规模大、能耗高,人们开始将更多的精力转移到深度学习硬件加速器的设计上来。和传统CPU和GPU芯片相比,深度学习硬件加速器有更高的性能和更低的能耗。未来随着人们真正进入智能时代,智能应用的普及会越来越广泛,到那时每台服务器、每台智能手机和每个智能摄像头,都需要使用深度学习加速器。 8 | 9 | 10 | ### 硬件加速器设计的思路 11 | :label:`accelerator-design-title` 12 | 13 | 近些年来,计算机体系结构的研究热点之一是深度学习硬件加速器的设计。在体系结构的研究中,能效和通用性是两个重要的衡量指标。其中能效关注单位能耗下基本计算的次数,通用性主要指芯片能够覆盖的任务种类。以两类特殊的芯片为例:一种是较为通用的通用处理器(如CPU),该类芯片理论上可以完成各种计算任务,但是其能效较低大约只有0.1TOPS/W。另一种是专用集成电路(Application Specific Integrated Circuit, ASIC),其能效更高,但是支持的任务相对而言就比较单一。对于通用的处理器而言,为了提升能效,在芯片设计上引入了许多加速技术,例如:超标量技术、单指令多数据(Single Instruction Multiple Data,SIMD)技术以及单指令多线程(Single Instruction Multiple Threads,SIMT)技术等。 14 | 15 | 对于不同的加速器设计方向,业界也有不同的硬件实现。针对架构的通用性,NVIDIA持续在GPU芯片上发力,先后推出了Volta、 Turing、 Ampere等架构,并推出用于加速矩阵计算的张量计算核心(Tensor Core),以满足深度学习海量算力的需求。 16 | 17 | 对于偏定制化的硬件架构,面向深度学习计算任务,业界提出了特定领域架构(Domain Specific Architecture, DSA)。Google公司推出了TPU芯片,专门用于加速深度学习计算任务,其使用脉动阵列(Systolic Array)来优化矩阵乘法和卷积运算,可以充分地利用数据局部性,降低对内存的访问次数。华为也推出了自研昇腾AI处理器,旨在为用户提供更高能效的算力和易用的开发、部署体验,其中的CUBE运算单元,就用于加速矩阵乘法的计算。 18 | -------------------------------------------------------------------------------- /chapter_accelerator/index.md: -------------------------------------------------------------------------------- 1 | # 硬件加速器 2 | 3 | 上一章节详细讨论了后端的计算图优化、算子选择以及内存分配。当前主流深度学习模型大多基于神经网络实现,无论是训练还是推理,都会产生海量的计算任务,尤其是涉及矩阵乘法这种高计算任务的算子。然而,通用处理器芯片如CPU在执行这类算子时通常耗时较大,难以满足训练和推理任务的需求。因此工业界和学术界都将目光投向特定领域的加速器芯片设计,希望以此来解决算力资源不足的问题。 4 | 5 | 6 | 本章将会着重介绍加速器的基本组成原理,并且以矩阵乘法为例,介绍在加速器上的编程方式及优化方法。 7 | 8 | 本章的学习目标包括: 9 | 10 | - 掌握加速器的基本组成 11 | 12 | - 掌握矩阵乘法的常见优化手段 13 | 14 | - 理解编程API的设计理念 15 | 16 | ```toc 17 | :maxdepth: 2 18 | 19 | accelerator_introduction 20 | accelerator_architecture 21 | accelerator_programming 22 | accelerator_practise 23 | summary 24 | ``` 25 | -------------------------------------------------------------------------------- /chapter_accelerator/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 面向深度学习计算任务,加速器通常都是由多种片上缓存以及多种运算单元组成来提升性能。 4 | 5 | - 未来性能增长需要依赖架构上的改变,即需要利用可编程的硬件加速器来实现性能突破。 6 | 7 | - 出于计算效率和易用性等原因,加速器一般会具有多个等级的编程方式,包括:算子库层级,编程原语层级和指令层级。 8 | 9 | - 越底层的编程方式越能够灵活地控制加速器,但同时对程序员的能力要求也越高。 10 | 11 | 12 | ## 扩展阅读 13 | 14 | - CUDA编程指导 [CUDA](https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html) 15 | - 昇腾社区 [Ascend](https://gitee.com/ascend) 16 | - MLIR应用进展 [MLIR](https://mlir.llvm.org/talks) 17 | 18 | 19 | ## 参考文献 20 | 21 | :bibliography:`../references/accelerator.bib` -------------------------------------------------------------------------------- /chapter_backend_and_runtime/graph_optimizer.md: -------------------------------------------------------------------------------- 1 | ## 计算图优化 2 | 3 | 后端的计算图优化主要是针对硬件的优化,根据优化适用于所有硬件还是只适合特定硬件,可以分为通用硬件优化和特定硬件优化,例如为了适配硬件指令限制而做的子图变换和与特定硬件无关的算子内存IO优化。 4 | 5 | ### 通用硬件优化 6 | 7 | 通用硬件优化主要指与特定硬件类型无关的计算图优化,优化的核心是子图的等价变换:在计算图中尝试匹配特定的子图结构,找到目标子图结构后,通过等价替换方式,将其替换成对硬件更友好的子图结构。 8 | 9 | 以优化内存IO为例。深度学习算子按其对资源的需求可以分为两类: 10 | 计算密集型算子,这些算子的时间绝大部分花在计算上,如卷积、全连接等; 11 | 访存密集型算子,这些算子的时间绝大部分花在访存上,他们大部分是Element-Wise算子,例如 ReLU、Element-Wise Sum等。 12 | 在典型的深度学习模型中,一般计算密集型和访存密集型算子是相伴出现的,最简单的例子是“Conv + ReLU”。Conv卷积算子是计算密集型,ReLU算子是访存密集型算子,ReLU算子可以直接取Conv算子的计算结果进行计算,因此可以将二者融合成一个算子来进行计算,从而减少内存访问延时和带宽压力,提高执行效率。 13 | 14 | 例如:“Conv + Conv + Sum + ReLU”的融合,从 :numref:`conv_sum_relu`中可以看到融合后的算子减少了两个内存的读和写的操作,优化了Conv的输出和Sum的输出的读和写的操作。 15 | 16 | ![Elementwise算子融合](../img/ch05/conv_sum_relu.png) 17 | :width:`800px` 18 | :label:`conv_sum_relu` 19 | 20 | 除了上述针对特定算子类型结构的融合优化外,基于自动算子生成技术,还可以实现更灵活、更极致的通用优化。以 MindSpore 的图算融合技术为例,图算融合通过“算子拆解、算子聚合、算子重建”三个主要阶段让计算图中的计算更密集,并进一步减少低效的内存访问。 21 | 22 | ![图算融合](../img/ch05/graph_kernel.png) 23 | :width:`800px` 24 | :label:`graph_kernel` 25 | 26 | :numref:`graph_kernel`中,算子拆解阶段(Expander)将计算图中一些复杂算子(composite 27 | op,图中Op1、Op3、Op4)展开为计算等价的基本算子组合( 28 | 图中虚线正方形框包围着的部分);在算子聚合阶段(Aggregation),将计算图中将基本算子(basic 29 | op,如图中Op2)、拆解后的算子(expanded 30 | op)组合融合,形成一个更大范围的算子组合;在算子重建阶段(Reconstruction)中,按照输入tensor到输出tensor的仿射关系将基本算子进行分类:elemwise、 31 | broadcast、reduce、transform等,并在这基础上归纳出不同的通用计算规则(如 32 | elemwise + reduce 规则:elemwise + 33 | reduce在满足一定条件后可以高效执行),根据这些计算规则不断地从这个大的算子组合上进行分析、筛选,最终重新构建成新的算子(如图中虚线正方形包围的两个算子 34 | New Op1 和 New 35 | Op2)。图算融合通过对计算图结构的拆解和聚合,可以实现跨算子边界的联合优化;并在算子重建中,通过通用的计算规则,以必要的访存作为代价,生成对硬件更友好、执行更高效的新算子。 36 | 37 | ### 特定硬件优化 38 | 39 | 特定硬件优化是指该计算图的优化是在特定硬件上才能做的优化,常见的基于硬件的优化包括由于硬件指令的限制而做的优化,特定硬件存储格式导致的优化等。 40 | 41 | 1、硬件指令限制 42 | 43 | 在一些特定的硬件上,IR中计算节点没有直接对应的硬件算子,只能通过子图的变换来达到子图中所有算子在对应的硬件上的存在。例如在MindSpore中,昇腾芯片上的Concat算子,只支持有限的输入个数(63个),因此当前端IR上的输入个数大于限制输入的时候,需要将该计算节点拆分成等价的多个Concat节点,如 :numref:`concat`所示: 44 | 当Concat有100个输入时,单个算子只支持最多63个输入,此时会将该计算节点拆分成两个Concat节点,分别为63个输入和37个输入的两个算子。 45 | 46 | ![Concat算子拆分](../img/ch05/concat.png) 47 | :width:`800px` 48 | :label:`concat` 49 | 50 | 2、数据排布格式的限制 51 | 52 | 针对不同特点的计算平台和不同的算子,为了追求最好的性能,一般都需要选择不同的数据排布格式(Format),而这些排布格式可能跟框架缺省的排布格式是不一样的。在这种情况下,一般的做法是算子在执行完成后对输出插入一个格式转换操作,把排布格式转换回框架的缺省排布格式,这就引入了额外的内存操作。以 :numref:`transdata`为例,在昇腾平台上Conv算子在输入和输出的内存排布为5HD时是性能最优的,所以可以看到Conv算子输出结果的格式是5HD,然后通过一个转换操作转回了框架缺省的NCHW,紧接着,后面又是一个Conv算子,它需要5HD的输入,所以又做了一个NCHW到5HD的转换。我们很容易看出,虚线框内的两个转换操作互为逆操作,可以相互抵消。通过对计算图的模式匹配,可以将该类型的操作消除。 53 | 54 | ![数据排布格式转换消除](../img/ch05/transdata.png) 55 | :width:`800px` 56 | :label:`transdata` 57 | -------------------------------------------------------------------------------- /chapter_backend_and_runtime/index.md: -------------------------------------------------------------------------------- 1 | # 编译器后端和运行时 2 | 3 | 在上一章节,详细讲述了一个AI编译器前端的主要功能,重点介绍了中间表示以及自动微分。在得到中间表示后,如何充分利用硬件资源高效地执行,是编译器后端和运行时要解决的问题。 4 | 5 | 在本章节中, 将会介绍AI编译器后端的一些基本概念,详细描述后端的计算图优化、算子选择等流程。通过对编译器前端提供的中间表示进行优化,充分发挥硬件能力,从而提高程序的执行效率。在此基础上,介绍运行时是如何对计算任务进行内存分配以及高效地调度执行。 6 | 7 | 本章的学习目标包括: 8 | 9 | - 了解编译器后端和运行时的作用 10 | 11 | - 掌握计算图优化的常用方法 12 | 13 | - 掌握算子选择的常用方法 14 | 15 | - 掌握内存分配的常用方法 16 | 17 | - 掌握计算图调度和执行的常用方法 18 | 19 | - 了解目前算子编译器的基本特点以及其尚未收敛的几个问题 20 | 21 | ```toc 22 | :maxdepth: 2 23 | 24 | overview 25 | graph_optimizer 26 | kernel_selecter 27 | memory_allocator 28 | compute_schedule_and_execute 29 | op_compiler 30 | summary 31 | ``` -------------------------------------------------------------------------------- /chapter_backend_and_runtime/overview.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | 编译器前端主要将用户代码进行解析翻译得到计算图IR,并对其进行设备信息无关的优化,此时的优化并不考虑程序执行的底层硬件信息。编译器后端的主要职责是对前端下发的IR做进一步的计算图优化,让其更加贴合硬件,并为IR中的计算节点选择在硬件上执行的算子,然后为每个算子的输入输出分配硬件内存,最终生成一个可以在硬件上执行的任务序列。 4 | 5 | 如 :numref:`compiler-backend-architecture`所示,编译器后端处于前端和硬件驱动层中间,主要负责计算图优化、算子选择和内存分配的任务。首先,需要根据硬件设备的特性将IR图进行等价图变换,以便在硬件上能够找到对应的执行算子,该过程是计算图优化的重要步骤之一。前端IR是通过解析用户代码生成的,属于一个较高的抽象层次,隐藏一些底层运行的细节信息,此时无法直接对应硬件上的算子(算子是设备上的基本计算序列,例如MatMul、Convolution、ReLU等),需要将细节信息进行展开后,才能映射到目标硬件上的算子。对于某些前端IR的子集来说,一个算子便能够执行对应的功能,此时可以将这些IR节点合并成为一个计算节点,该过程称之为算子融合;对于一些复杂计算,后端并没有直接与之对应的算子,但是可以通过几个基本运算的算子组合达到同样的计算效果,此时可以将前端IR节点拆分成多个小算子。在完成计算图优化之后,就要进行算子选择过程,为每个计算节点选择执行算子。算子选择是在得到优化的IR图后选取最合适的目标设备算子的过程。针对用户代码所产生的IR往往可以映射成多种不同的硬件算子,但是这些不同硬件算子的执行效率往往有很大差别,如何根据前端IR选择出最高效的算子,是算子选择的核心问题。算子选择本质上是一个模式匹配问题。其最简单的方法就是每一个IR节点对应一个目标硬件的算子,但是这种方法往往对目标硬件的资源利用比较差。现有的编译器一般都对每一个IR节点提供了多个候选的算子,算子选择目标就是从中选择最优的一个算子作为最终执行在设备上的算子。总的来说,在机器学习系统中,对前端生成的IR图上的各个节点进行拆分和融合,让前端所表示的高层次IR逐步转换为可以在硬件设备上执行的低层次IR。得到了这种更加贴合硬件的IR后,对于每个单节点的IR可能仍然有很多种不同的选择,例如可以选择不同的输入输出格式和数据类型,需要对IR图上每个节点选择出最为合适的算子,算子选择过程可以认为是针对IR图的细粒度优化过程,最终生成完整的算子序列。最后,遍历算子序列,为每个算子分配相应的输入输出内存,然后将算子加载到设备上执行计算。 6 | 7 | ![编译器后端总体架构简图](../img/ch05/compiler-backend-architecture.png) 8 | :width:`800px` 9 | :label:`compiler-backend-architecture` 10 | 11 | ### 计算图优化 12 | 13 | 计算图优化是在不影响模型的数值特性的基础上,通过图变换达到简化计算、减少资源开销、适配硬件的执行能力、提升执行性能的目的。 14 | 15 | ### 算子选择 16 | 17 | 算子选择是将IR图上的每个计算节点映射到设备上可执行算子的过程,一个IR图上的计算节点往往可以对应多个设备上的算子,这个过程中需要考虑算子的规格,算子的执行效率等问题,算子选择目标就是从中选择最优的一个算子。 18 | 19 | ### 内存分配 20 | 21 | 经过计算图优化和算子选择之后,我们可以得到IR图中每个算子的输入输出的形状(Shape)、数据类型、存储格式。根据这些信息,计算输入输出数据的大小,并为输入输出分配设备上的内存,然后将算子加载到设备上才能真正执行计算。此外,为了更充分地例用设备内存资源,可以对内存进行复用,提高内存利用率。 22 | 23 | ### 计算调度与执行 24 | 25 | 经过算子选择与内存分配之后,计算任务可以通过运行时完成计算的调度与在硬件上的执行。根据是否将算子编译为计算图,计算的调度可以分为单算子调度与计算图调度两种方式。而根据硬件提供的能力差异,计算图的执行方式又可以分为逐算子下发执行的交互式执行以及将整个计算图或者部分子图一次性下发到硬件的下沉式执行两种模式。 26 | 27 | ### 算子编译器 28 | 29 | 作为AI编译器中一个重要组成部分,算子编译器把单个简单或复杂的算子经过表达和优化后编译为一个单独的可执行文件。目前业界面对算子编译器仍有许多有趣的问题尚未得出明确结论,相关的处理逻辑与方法也尚未收敛。本小节希望将这些问题简单抛出,并给出业界比较典型的几种处理方式。若能对业界朋友们和同学们有所启发甚至若能对这些问题起到促进收敛的作用,那真是再好不过!目前尚待收敛的问题包括而不限于:如何通过算子编译器进行性能优化?算子编译器如何兼容不同体系结构特点的芯片?面对输入Python代码的灵活性以及神经网络训练时动态性的情况,该如何充分将这些完美表达出来? 30 | -------------------------------------------------------------------------------- /chapter_backend_and_runtime/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 编译器后端主要负责计算图优化、算子选择、内存分配这三个任务。 4 | 5 | - 计算图优化是在不影响模型的数值特性的基础上,通过图变换达到减少资源开销、适配硬件的执行能力、提升执行性能的目的。 6 | 7 | - 计算图优化主要分为硬件通用优化和特定硬件优化,例如与硬件无关的算子内存IO优化和为了适配特定硬件指令限制而做的子图变换。 8 | 9 | - 算子选择是为IR图中的每个计算节点选择一个最适合在设备上执行的算子。 10 | 11 | - 数据存在多种存储格式和计算精度,不同的存储格式和计算精度在不同场景下对算子计算性能有较大的影响,所以算子选择需要综合考虑各方面影响选择最优的算子。 12 | 13 | - 经过计算图优化和算子选择之后,得到了最终的IR。基于最终的IR,需要为算子的输入输出Tensor分配内存,然后加载算子到硬件上执行。 14 | 15 | - 内存复用是一个重要的内存分配优化手段,可以让设备上容纳更大的网络模型。 16 | 17 | - 将通信算子的内存进行融合,可以提高通信的效率;合理分配In-Place算子的内存,可以节省内存使用并且提高计算效率。 18 | 19 | - 运行时对于算子的执行可以分为单算子调度和计算图调度两种模式,而在计算图调度模式中,根据具体硬件的能力又可以分为交互式执行和下沉式执行两种方式,交互式执行具备更多的灵活性,下沉执行可以获得更好的计算性能。 20 | 21 | - 算子编译器是优化硬件性能的关键组件。其中,调度策略的优化和基于多面体模型算法的优化是两个关键技术。 22 | 23 | ## 扩展阅读 24 | 25 | - 内存分配作为机器学习后端的重要部分,建议阅读 [Sublinear Memory Cost](https://arxiv.org/abs/1604.06174)、 [Dynamic Tensor Rematerialization](https://arxiv.org/abs/2006.09616)。 26 | - 对于运行时的调度以及执行,建议阅读 [A Lightweight Parallel and Heterogeneous Task Graph Computing System](https://arxiv.org/abs/2004.10908)、 [Dynamic Control Flow in Large-Scale Machine Learning](https://arxiv.org/abs/1805.01772)、[DEEP LEARNING WITH DYNAMIC COMPUTATION GRAPHS](https://arxiv.org/abs/1702.02181)。 27 | - 算子编译器是本书的扩展部分,建议阅读提出计算与调度分离的论文: [Halide: A Language and Compiler for Optimizing Parallelism, Locality, and Recomputation in Image Processing Pipelines](https://dl.acm.org/doi/abs/10.1145/2499370.2462176),以及介绍调度空间优化的论文 [Ansor: Generating High-Performance Tensor Programs for Deep Learning](https://arxiv.org/abs/2006.06762)和 [olly - Polyhedral optimization in LLVM](https://arxiv.org/abs/2105.04555) 28 | -------------------------------------------------------------------------------- /chapter_computational_graph/background_and_functionality.md: -------------------------------------------------------------------------------- 1 | ## 计算图的设计背景和作用 2 | 3 | ![基于计算图的架构](../img/ch03/graph.png) 4 | :width:`800px` 5 | :label:`dag` 6 | 7 | 早期机器学习框架主要针对全连接和卷积神经网络设计,这些神经网络的拓扑结构简单,神经网络层之间通过串行连接。因此,它们的拓扑结构可以用简易的配置文件表达(例如Caffe基于Protocol Buffer格式的模型定义)。 8 | 9 | 现代机器学习模型的拓扑结构日益复杂,显著的例子包括混合专家模型、生成对抗网络、注意力模型等。复杂的模型结构(例如带有分支的循环结构等)需要机器学习框架能够对模型算子的执行依赖关系、梯度计算以及训练参数进行快速高效的分析,便于优化模型结构、制定调度执行策略以及实现自动化梯度计算,从而提高机器学习框架训练复杂模型的效率。因此,机器学习系统设计者需要一个通用的数据结构来理解、表达和执行机器学习模型。为了应对这个需求,如 :numref:`dag`所示基于计算图的机器学习框架应运而生,框架延续前端语言与后端语言分离的设计。从高层次来看,计算图实现了以下关键功能: 10 | 11 | - **统一的计算过程表达。** 12 | 在编写机器学习模型程序的过程中,用户希望使用高层次编程语言(如Python、Julia和C++)。然而,硬件加速器等设备往往只提供了C和C++编程接口,因此机器学习系统的实现通常需要基于C和C++。用不同的高层次语言编写的程序因此需要被表达为一个统一的数据结构,从而被底层共享的C和C++系统模块执行。这个数据结构(即计算图)可以表述用户的输入数据、模型中的计算逻辑(通常称为算子)以及算子之间的执行顺序。 13 | 14 | - **自动化计算梯度。** 15 | 用户的模型训练程序接收训练数据集的数据样本,通过神经网络前向计算,最终计算出损失值。根据损失值,机器学习系统为每个模型参数计算出梯度来更新模型参数。考虑到用户可以写出任意的模型拓扑和损失值计算方法,计算梯度的方法必须通用并且能实现自动运行。计算图可以辅助机器学习系统快速分析参数之间的梯度传递关系,实现自动化计算梯度的目标。 16 | 17 | - **分析模型变量生命周期。** 18 | 在用户训练模型的过程中,系统会通过计算产生临时的中间变量,如前向计算中的激活值和反向计算中的梯度。前向计算的中间变量可能与梯度共同参与到模型的参数更新过程中。通过计算图,系统可以准确分析出中间变量的生命周期(一个中间变量生成以及销毁时机),从而帮助框架优化内存管理。 19 | 20 | - **优化程序执行。** 21 | 用户给定的模型程序具备不同的网络拓扑结构。机器学习框架利用计算图来分析模型结构和算子执行依赖关系,并自动寻找算子并行计算的策略,从而提高模型的执行效率。 -------------------------------------------------------------------------------- /chapter_computational_graph/index.md: -------------------------------------------------------------------------------- 1 | # 计算图 2 | 3 | 上一章节展示了如何高效编写机器学习程序,那么下一个问题就是:机器学习系统如何高效地在硬件上执行这些程序呢?这一核心问题又能被进一步拆解为:如何对机器学习程序描述的模型调度执行?如何使得模型调度执行更加高效?如何自动计算更新模型所需的梯度?解决这些问题的关键是计算图(Computational Graph)技术。为了讲解这一技术,本章将详细讨论计算图的基本组成、自动生成和高效执行中所涉及的方法。 4 | 5 | 本章的学习目标包括: 6 | - 掌握计算图的基本构成。 7 | - 掌握计算图静态生成和动态生成方法。 8 | - 掌握计算图的常用执行方法。 9 | 10 | ```toc 11 | :maxdepth: 2 12 | 13 | background_and_functionality 14 | components_of_computational_graph 15 | generation_of_computational_graph 16 | schedule_of_computational_graph 17 | summary 18 | ``` -------------------------------------------------------------------------------- /chapter_computational_graph/schedule_of_computational_graph.md: -------------------------------------------------------------------------------- 1 | ## 计算图的调度 2 | 3 | 模型训练就是计算图调度图中算子的执行过程。宏观来看训练任务是由设定好的训练迭代次数来循环执行计算图,此时需要优化迭代训练计算图过程中数据流载入和训练(推理)执行等多个任务之间的调度策略。微观上单次迭代需要考虑计算图内部的调度执行问题,根据计算图结构、计算依赖关系、计算控制分析算子的执行调度。优化计算图的调度和执行性能,目的是尽可能充分利用计算资源,提高计算效率,缩短模型训练和推理时间。接下来会详细介绍计算图的调度和执行。 4 | 5 | ### 算子调度执行 6 | 7 | 算子的执行调度包含两个步骤,第一步,根据拓扑排序算法,将计算图进行拓扑排序得到线性的算子调度序列;第二步,将序列中的算子分配到指令流进行运算,尽可能将序列中的算子并行执行,提高计算资源的利用率。 8 | 9 | 计算图是一种由依赖边和算子构成的有向无环图,机器学习框架后端需要将包含这种依赖关系的算子准确地发送到计算资源,比如GPU、NPU上执行。针对有向无环图,通常使用拓扑排序来得到一串线性的序列。 10 | 11 | 如 :numref:`schedule`所示,左边是一张有向无环图。图中包含了a、b、c、d、e五个节点和a->d、b->c、c->d、d->e四条边(a->d表示d依赖于a,称为依赖边)。将图的依赖边表达成节点的入度(图论中通常指有向图中某点作为图中边的终点的次数之和),可以得到各个节点的入度信息(a:0、 b:0、 c:1、 d:2、 e:1)。拓扑排序就是不断循环将入度为0的节点取出放入队列中,直至有向无环图中的全部节点都加入到队列中,循环结束。例如,第一步将入度为0的a、b节点放入到队列中,此时有向无环图中c、d的入度需要减1,得到新的入度信息(c:0、d:1、e:1)。以此类推,将所有的节点都放入到队列中并结束排序。 12 | 13 | ![算子调度执行](../img/ch03/schedule.svg) 14 | :width:`700px` 15 | :label:`schedule` 16 | 17 | 生成调度序列之后,需要将序列中的算子与数据分发到指定的GPU/NPU上执行运算。根据算子依赖关系和计算设备数量,可以将无相互依赖关系的算子分发到不同的计算设备,同时执行运算,这一过程称之为并行计算,与之相对应的按照序贯顺序在同一设备执行运算被称为串行计算。在深度学习中,当数据集和参数量的规模越来越大在分发数据与算子时通信消耗会随之而增加,计算设备会在数据传输的过程中处于闲置状态。此时采用同步与异步的任务调度机制可以更好的协调通信与训练任务,提高通信模块与计算设备的使用率,在后续的小节中将详细介绍串行与并行、同步与异步的概念。 18 | 19 | ### 串行与并行 20 | 21 | 根据任务队列的执行顺序,我们可以将计算图的任务调度队列分为以下两种: 22 | 23 | - **串行**:队列中的任务必须按照顺序进行调度执行直至队列结束; 24 | 25 | - **并行**:队列中的任务可以同时进行调度执行,加快执行效率。 26 | 27 | 首先从微观上来分析计算图内部的串行调度。计算图中大多数算子之间存在直接依赖或者间接依赖关系,具有依赖关系的算子间任务调度则必定存在执行前后的时间顺序。如 :numref:`order`,计算图接受输入数据进行前向计算得到预测值,计算损失函数进行反向梯度计算,整体代码流程后序算子的计算有赖于前序算子的输出。此时算子的执行队列只能以串行的方式进行调度,保证算子都能正确接受到输入数据,才能完成计算图的一次完整执行。 28 | 29 | ![算子的串行](../img/ch03/order.png) 30 | :width:`800px` 31 | :label:`order` 32 | 33 | 宏观上来看迭代训练之间,每一轮迭代中计算图必须读取训练数据,执行完整的前向计算和反向梯度计算,将图中所有参数值更新完毕后,才能开始下一轮的计算图迭代计算更新。所以“数据载入-数据预处理-模型训练”的计算图整体任务调度是以串行方式进行的。 34 | 35 | 在分析计算图内部算子依赖关系时,除了直接依赖和间接依赖之外,存在算子间相互独立的情况。如 :numref:`para`中op1和op2之间相互独立,此时可以将两个算子分配到两个硬件上进行并行计算。对比串行执行,并行计算可以同时利用更多的计算资源来缩短执行时间。 36 | 37 | ![算子的并行](../img/ch03/para.svg) 38 | :width:`800px` 39 | :label:`para` 40 | 41 | 并行包括算子并行、模型并行以及数据并行。算子并行不仅可以在相互独立的算子间实现,同时也可以将单个算子合理的切分为相互独立的多个子操作,进一步提高并行性。模型并行就是将整体计算图进行合理的切分,分配到不同设备上进行并行计算,缩短单次计算图迭代训练时间。数据并行则同时以不同的数据训练多个相同结构的计算图,减少训练迭代次数,加快训练效率。这三种并行方式将在后续章节中进行详细讲解。 42 | 43 | ### 数据载入同步与异步机制 44 | 45 | 一次完整计算图的训练执行过程包含:数据载入、数据预处理、网络训练三个环节。三个环节之间的任务调度是以串行方式进行,每一个环节都有赖于前一个环节的输出。但计算图的训练是多轮迭代的过程,多轮训练之间的三个环节可以用同步与异步两种机制来进行调度执行。 46 | 47 | - **同步**:顺序执行任务,当前任务执行完后会等待后续任务执行情况,任务之间需要等待、协调运行; 48 | 49 | - **异步**:当前任务完成后,不需要等待后续任务的执行情况,可继续执行当前任务下一轮迭代。 50 | 51 | 以同步机制来执行计算图训练时,如 :numref:`synchronization`所示,每一轮迭代中,数据载入后进行数据预处理操作,然后传输给计算图进行训练。每一个环节执行完当前迭代中的任务后,会一直等待后续环节的处理,直至计算图完成一次迭代训练更新参数值后,才会进行下一轮迭代的数据载入、数据预处理以及网络训练。当进行数据载入时,数据预处理、模型训练处于等待的状态;同样的,模型处于训练时,数据载入的I/O通道处于空闲,同步机制造成计算资源和通信资源的浪费。 52 | 53 | ![同步机制](../img/ch03/synchronization.svg) 54 | :width:`800px` 55 | :label:`synchronization` 56 | 57 | 以异步机制来执行计算图训练时,如 :numref:`asynchronous`所示,在迭代训练中,当数据通道载入数据后交给后续的数据预处理环节后,不需要等待计算图训练迭代完成,直接读取下一批次的数据。对比同步机制,异步机制的引入减少了数据载入、数据预处理、网络训练三个环节的空闲等待时间,能够大幅度缩短迭代训练的整体时间,提高任务执行效率。 58 | 59 | ![异步机制](../img/ch03/asynchronous.svg) 60 | :width:`800px` 61 | :label:`asynchronous` 62 | 63 | 将异步机制与并行计算结合在一起,如 :numref:`asyn_para`所示,一方面异步机制减少模型等待数据载入和预处理的时间,另一方面并行计算增加了单轮模型训练接受的数据量。相比于不采用异步机制和同步计算,机器学习框架可以利用丰富的计算资源更快速的遍历训练完数据集,缩短训练时间提高计算效率。 64 | 65 | ![异步并行](../img/ch03/asyn_para.svg) 66 | :width:`800px` 67 | :label:`asyn_para` 68 | -------------------------------------------------------------------------------- /chapter_computational_graph/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 为了兼顾编程的灵活性和计算的高效性,设计了基于计算图的机器学习框架。 4 | 5 | - 计算图的基本数据结构是张量,基本运算单元是算子。 6 | 7 | - 计算图可以表示机器学习模型的计算逻辑和状态,利用计算图分析图结构并进行优化。 8 | 9 | - 计算图是一个有向无环图,图中算子间可以存在直接依赖和间接依赖关系,或者相互关系独立,但不可以出现循环依赖关系。 10 | 11 | - 可以利用控制流来改变数据在计算图中的流向,常用的控制流包括条件控制和循环控制。 12 | 13 | - 计算图的生成可以分为静态生成和动态生成两种方式。 14 | 15 | - 静态图计算效率高,内存使用效率高,但调试性能较差,可以直接用于模型部署。 16 | 17 | - 动态图提供灵活的可编程性和可调试性,可实时得到计算结果,在模型调优与算法改进迭代方面具有优势。 18 | 19 | - 利用计算图和算子间依赖关系可以解决模型中的算子执行调度问题。 20 | 21 | - 根据计算图可以找到相互独立的算子进行并发调度,提高计算的并行性。而存在依赖关系的算子则必须依次调度执行。 22 | 23 | - 计算图的训练任务可以使用同步或者异步机制,异步能够有效提高硬件使用率,缩短训练时间。 24 | 25 | ## 扩展阅读 26 | 27 | - 计算图是机器学习框架的核心理念之一,了解主流机器学习框架的设计思想,有助于深入掌握这一概念,建议阅读 [TensorFlow 设计白皮书](https://arxiv.org/abs/1603.04467)、 [PyTorch计算框架设计论文](https://arxiv.org/abs/1912.01703)。 28 | - 图外控制流直接使用前端语言控制流,熟悉编程语言即可掌握这一方法,而图内控制流则相对较为复杂,建议阅读[TensorFlow控制流](http://download.tensorflow.org/paper/white_paper_tf_control_flow_implementation_2017_11_1.pdf)论文。 29 | - 动态图和静态图设计理念与实践,建议阅读[TensorFlow Eager 论文](https://arxiv.org/pdf/1903.01855.pdf)、[TensorFlow Eager Execution](https://tensorflow.google.cn/guide/eager?hl=zh-cn)示例、[TensorFlow Graph](https://tensorflow.google.cn/guide/intro_to_graphs?hl=zh-cn)理念与实践、[MindSpore动静态图](https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/design/dynamic_graph_and_static_graph.html)概念。 -------------------------------------------------------------------------------- /chapter_data_processing/data_order.md: -------------------------------------------------------------------------------- 1 | ## 保序性设计 2 | 3 | 和常规数据并行计算任务不同的是,机器学习场景下的数据并行处理为了确保实验的可复现性需要维护保序的性质。在具体实现中,我们需要保证并行数据预处理后的数据输出顺序与输入顺序保持相同(即下图中的SeqB和SeqA相同)。这确保了每一次的数据模块的结果输出顺序由数据混洗模块输出顺序唯一确定,有助于用户在不同的实验之间进行比较和调试。不同的机器学习系统采用了不同的方案来确保保序性,我们以MindSpore的实现为例子进行介绍以加深读者对这部分内容的理解。 4 | 5 | ![数据的保序性——确保SeqB与SeqA相同](../img/ch07/7.4/data_ordering.png) 6 | :width:`800px` 7 | :label:`data_order_definition` 8 | 9 | MindSpore通过约束算子线程组间的通信行为来确保对当前算子的下游算子的输入顺序与自己的输入顺序相同,基于这种递归的约束,确保了整个并行数据处理最后一个算子的输出顺序与第一个算子的输入顺序相同。具体实现中,MindSpore以Connector为算子线程组间的通信组件,对Connector的核心操作为上游算子的Push操作以及下游算子的Pop操作,我们重点关注MindSpore对这两个行为的约束。 10 | 11 | Connector的使用有如下两个要求: 12 | 13 | - Connector两端的数据生产线程组和数据消费线程组中的线程分别从0开始编号。 14 | 15 | - 确保数据生产者的输入数据顺序是在各个生产者线程间为按顺序轮询分布(Round-Robin distribution), 即当生产者线程组大小为M时,生产者线程0拥有第(0 + M \* k)个数据,生产者线程1拥有第(1 + M \* k),生产者线程2拥有第(2 + M \* k)个数据等(其中k=0,1,2,3\...)。 16 | 17 | Connector中维护与生产者线程数目相同的队列并确保向Connector中放入数据时,每个生产者线程生产的数据只放到对应编号的队列中,这样可以确保Connector中的数据在不同的队列间的分布与在不同生产者线程组之间的分布相同(代码片段中的Push函数)。接着当Connector的消费者线程组从Connector中获取数据时,我们需要确保最终数据在不同的消费者线程间依然为按顺序轮询分布,即当消费者线程组大小为N时,消费者线程0拥有第(0 + N \* k)个数据,消费者线程1拥有第(1 + N \* k)个数据,消费者线程2拥有第(2 + N \* k)个数据等(其中k=0,1,2,3\...)。为此当有消费者线程从Connector中请求数据时,Connector在确保当前请求消费者线程编号i与待消费数据标号j符合$i=j\%N$的关系下(其中N为消费者线程数目)按照轮循的方式从各个队列中获取数据,如果二者标号不符合上述关系,则该请求阻塞等待。通过这种通信的约束方式,MindSpore实现了保序功能。 18 | 19 | ![MindSpore保序性实现](../img/ch07/7.4/mindspore_data_order.jpeg) 20 | :width:`800px` 21 | :label:`mindspore_data_order_implementation` 22 | -------------------------------------------------------------------------------- /chapter_data_processing/extension.md: -------------------------------------------------------------------------------- 1 | ## 单机数据处理性能的扩展 2 | 3 | 上文我们介绍了通过并行架构发挥多核CPU算力来加速数据预处理,以满足芯片上模型计算对于数据消费的吞吐率需求,这在大部分情况下都能解决用户的问题。然而数据消费性能随着AI芯片的发展在逐年快速增长(即模型计算速率在变快),而主要借助CPU算力的数据模块却由于摩尔定律的逐渐终结无法享受到芯片性能提升带来的硬件红利,使得数据生产的性能很难像模型计算性能一样逐年突破。不仅如此,近几年AI服务器上AI芯片数量的增长速度远超CPU数量的增长速度,进一步加剧了芯片的数据消费需求与数据模块的数据生产性能之间的矛盾。我们以英伟达(NVIDIA)公司生产的NVIDIA DGX系列服务器为例子,DGX-1服务器中配置有40个CPU核和8个GPU芯片,而到了下一代的NVIDIA DGX-2服务器时,GPU芯片的数目增长了到了16个,而CPU核的数目仅从40个增加到了48个。由于所有的GPU芯片在训练时共享CPU的算力,故平均而言每个GPU芯片(数据消费者)能够使用的算力从NVIDIA DGX-1时的5CPU核/GPU下降到了 NVIDIA DGX-2的3CPU核/GPU,CPU的算力瓶颈会导致用户使用多卡训练时无法达到预期的扩展性能。针对单机上的CPU算力不足的问题,我们给出两种目前常见的两种解决方案,即基于CPU+AI芯片的异构数据处理的加速方案和基于分布式数据预处理的扩展方案。 4 | 5 | ### 基于异构计算的数据预处理 6 | 7 | 由于AI芯片相比于CPU拥有更丰富的算力资源,故在CPU算力成为数据预处理瓶颈时通过借助AI加速芯片来做数据预处理是一个行之有效的方案。虽然AI芯片不具备通用的数据预处理能力,但是由于大部分高耗时的数据预处理都是Tensor相关的计算,如语音中的快速傅立叶变换(Fast Fourier Transform, FFT),图像中的去噪等,使得部分操作可以被卸载到AI芯片上来加速。如华为昇腾Ascend310芯片上的Dvpp模块为芯片内置的硬件解码器,相较于CPU拥有对图形处理更强劲的性能,Dvpp支持JPEG图片的解码缩放等图像处理基础操作,用户实际数据预处理中可以指定部分图像处理在昇腾Ascend310芯片上完成以提升数据模块性能。 8 | 9 | ```python 10 | namespace ms = mindspore; 11 | namespace ds = mindspore::dataset; 12 | 13 | // 初始化操作 14 | //... 15 | 16 | // 构建数据处理算子 17 | 18 | // 1. 解码 19 | std::shared_ptr decode(new ds::vision::Decode()); 20 | // 2. 缩放 21 | std::shared_ptr resize(new ds::vision::Resize({256})); 22 | // 3. 归一化 23 | std::shared_ptr normalize(new ds::vision::Normalize( 24 | {0.485 * 255, 0.456 * 255, 0.406 * 255}, {0.229 * 255, 0.224 * 255, 0.225 * 255})); 25 | // 4. 剪裁 26 | std::shared_ptr center_crop(new ds::vision::CenterCrop({224, 224})); 27 | 28 | // 构建流水并指定使用昇腾Ascend进行计算 29 | ds::Execute preprocessor({decode, resize, center_crop, normalize}, MapTargetDevice::kAscend310, 0); 30 | 31 | // 执行数据处理流水 32 | ret = preprocessor(image, &image); 33 | ``` 34 | 35 | 相比较Dvpp只支持图像的部分预处理操作,英伟达公司研发的DALI :cite:`nvidia_dali`是一个更加通用的基于GPU的数据预处理加速框架。DALI中包含如下三个核心概念: 36 | 37 | - DataNode:表示一组Tensor的集合 38 | 39 | - Operator:对DataNode进行变换处理的算子,一个Operator的输入和输出均为DataNode。比较特殊的是,DALI中的算子可以被设置为包括cpu,gpu,mixed三种不同执行模式,其中cpu模式下算子的输入输出均为cpu上的DataNode,gpu模式下算子的输入输出均为gpu上的DataNode,而mixed模式下的算子的输入为cpu的DataNode而输出为gpu的DataNode。 40 | 41 | - Pipeline:用户通过Operator描述DataNode的处理变换过程而构建的数据处理流水 42 | 43 | 实际使用中用户通过设置算子的运行模式(mode)来配置算子的计算是用CPU还是GPU完成计算,同时DALI中有如下限制:当一个算子为mixed模式或者gpu模式时,其所有的下游算子强制要求必须为gpu模式执行。 44 | 45 | ![NVIDIA DALI概览](../img/ch07/7.5/dali_overview.png) 46 | 47 | :width:`800px` 48 | :label:`dali_overview` 49 | 50 | 下面展示一段使用DALI构建数据处理流水线的示例代码,我们从文件中读取图片数据经过混合模式的解码再经过运算在GPU上的旋转和缩放算子处理后返回给用户处理 51 | 结果。由于其展示出的优异性能, 52 | DALI被广泛的用于高性能推理服务和多卡训练性能的优化上。 53 | 54 | 55 | ```python 56 | import nvidia.dali as dali 57 | 58 | pipe = dali.pipeline.Pipeline(batch_size = 3, num_threads = 2, device_id = 0) 59 | with pipe: 60 | files, labels = dali.fn.readers.file(file_root = "./my_file_root") 61 | images = dali.fn.decoders.image(files, device = "mixed") 62 | images = dali.fn.rotate(images, angle = dali.fn.random.uniform(range=(-45,45))) 63 | images = dali.fn.resize(images, resize_x = 300, resize_y = 300) 64 | pipe.set_outputs(images, labels) 65 | 66 | pipe.build() 67 | outputs = pipe.run() 68 | ``` 69 | 70 | ### 基于分布式的数据预处理 71 | 72 | 分布式数据预处理是另一种解决CPU算力性能不足的可选方案。一种常见的做法是借助Spark、Dask等现有大数据计算框架进行数据预处理并将结果写入分布式文件系统,而训练的机器只需要读取预处理的结果数据并进行训练即可。 73 | 74 | ![基于第三方分布式计算框架的分布式数据预处理](../img/ch07/7.5/distribute.png) 75 | 76 | :width:`800px` 77 | :label:`distributed_data_preprocess_based_on_3rd_party_software` 78 | 79 | 该方案虽然在业内被广泛使用,却面临着三个问题: 80 | 81 | - 由于数据处理和数据训练采用不同的框架,使得用户为此常常需要在两个不同的框架中编写不同语言的程序,增加了用户的使用负担。 82 | 83 | - 由于数据处理系统和机器学习两个系统间无法做零拷贝的数据共享,使得数据的序列化和反序列化常常成为不可忽视的额外开销。 84 | 85 | - 由于大数据计算框架并不是完全针对机器学习场景,使得某些分布式预处理操作如全局的数据混洗无法被高效的实现。 86 | 87 | 为了更适配机器学习场景的数据预处理,分布式机器学习框架Ray借助其自身的任务调度能力实现了简单的分布式的数据预处理------ 88 | Ray Dataset :cite:`moritz2018ray`,由于数据预处理和训练处在同一个框架内,在降低了用户的编程负担的同时也通过数据的零拷贝共享消除了序列化/反序列化带来的额外开销。Ray Dataset支持如map、batch、map、filter等简单并行数据集变换算子、以及如mean等一些基础的聚合操作算子。同时Ray 89 | Dataset也支持排序、随机打乱、GroupBy等全局混洗操作,该方案目前处在研究开发中,还未被广泛的采用,感兴趣的读者可以翻阅相关资料进一步的了解。 90 | 91 | ```python 92 | ray.data.read_parquet("foo.parquet") \ 93 | .filter(lambda x: x < 0) \ 94 | .map(lambda x: x**2) \ 95 | .random_shuffle() \ 96 | .write_parquet("bar.parquet") 97 | ``` 98 | -------------------------------------------------------------------------------- /chapter_data_processing/index.md: -------------------------------------------------------------------------------- 1 | # 数据处理框架 2 | 3 | 在前两个章节中,我们介绍了编译器前后端的相关内容,详细地阐述了源程序到目标程序的转换优化过程。除了让芯片在训练/推理过程中高性能地运行,我们还需要将数据高效地发送给芯片,以实现全流程的性能最优。机器学习模型训练和推理需要从存储设备(如本地磁盘和内存、远端的存储系统等)中加载数据集,对数据集进行一系列处理变换,将处理结果发送到GPU或者华为昇腾Ascend等加速器中完成模型计算,该流程的任何一个步骤出现性能问题都会对训练和推理的吞吐率造成负面影响。本章我们将核心介绍如何设计、并实现一个面向机器学习场景的数据系统,以帮助用户轻松构建各种复杂的数据处理流水线(Data 4 | Pipeline),同时我们的数据系统要有足够高的执行性能,以确保数据预处理步骤不会成为模型训练和推理的性能瓶颈。 5 | 6 | 本章主要从易用性、高效性和保序性三个维度展开介绍机器学习系统中的数据模块。在前两个小节中,我们首先讨论如何构建一个易用的数据模块。包括如何设计编程抽象,使得用户通过短短几行代码便可以描述一个复杂的预处理过程;以及如何做到既内置丰富算子提升易用性,又可以灵活支持用户使用自定义算子覆盖长尾需求。用户构建好数据处理流程后,数据模块需要负责高效的调度执行数据流水线,以达到最优的数据处理吞吐率。高效的执行数据流水线是一个具有挑战性的任务,我们既要面临数据读取部分的I/O性能问题,又要解决数据处理部分的计算性能问题。针对上述挑战,我们将分别介绍面向高吞吐率读取性能的数据文件格式设计,以及能够充分发挥多核CPU算力的并行架构设计。不仅如此,和常规数据并行计算任务不同的是,大部分机器学习场景对于数据的输入输出顺序有着特殊的`保序性`的要求,我们将会使用一节的内容来介绍什么是保序性,以及如何在数据模块的并行架构中设计相应组件计来满足该特性需求。学习了上述的内容后,读者将会对如何构建一个面向机器学习场景高效易用的数据模块有深刻的理解。最后,作为拓展内容,我们将以目前学术界和业界的一些实践经验来介绍当单机处理性能达不到要求时,该如何去扩展我们的数据处理模块以满足训练性能需求。本章学习目标包括: 7 | 8 | - 了解机器学习数据模块架构中的关键组件及其功能 9 | 10 | - 了解不同数据模块用户编程接口的设计 11 | 12 | - 掌握面向高性能数据读取的数据文件格式设计 13 | 14 | - 掌握机器学习系统数据模块并行架构 15 | 16 | - 掌握机器学习系统数据模块数据保序性含义及其解决方案 17 | 18 | - 了解两种单机数据处理性能扩展方案 19 | 20 | 21 | ```toc 22 | :maxdepth: 2 23 | 24 | requirements 25 | program_model 26 | performance 27 | data_order 28 | extension 29 | summary 30 | ``` -------------------------------------------------------------------------------- /chapter_data_processing/requirements.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | 机器学习场景中的数据处理是一个典型的ETL(Extract, Transform, 4 | Load)过程,第一个阶段(Extract)需要从存储设备中加载数据集,第二个阶段(Transform)完成对数据集的变换处理。虽然不同的机器学习系统在构建数据模块时采用了不同的技术方案,但其核心都会包含数据加载、数据混洗、数据变换、数据mini-batch组装以及数据发送等关键组件。其中每个组件的功能介绍如下所示: 5 | 6 | - **数据加载组件(Load)**:负责从存储设备中加载读取数据集,需要同时考虑存储设备的多样性(如本地磁盘/内存,远端磁盘和内存等)和数据集格式的多样性(如csv格式,txt格式等)。根据机器学习任务的特点,AI框架也提出了统一的数据存储格式(如谷歌TFRecord, 7 | 华为MindRecord等)以提供更高性能的数据读取。 8 | 9 | - **数据混洗组件(Shuffle)**:负责将输入数据的顺序按照用户指定方式随机打乱,以提升模型的鲁棒性。 10 | 11 | - **数据变换组件(Map)**:负责完成数据的变换处理,内置面向各种数据类型的常见预处理算子,如图像中的尺寸缩放和翻转,音频中的随机加噪和变调、文本处理中的停词去除和随机遮盖(Mask)等。 12 | 13 | - **数据组装组件(Batch)**:负责组装构造一个批次(mini-batch)的数据发送给训练/推理。 14 | 15 | - **数据发送组件(Send)**:负责将处理后的数据发送到GPU/华为昇腾Ascend等加速器中以进行后续的模型计算和更新。高性能的数据模块往往选择将数据向设备的搬运与加速器中的计算异步执行,以提升整个训练的吞吐率。 16 | 17 | ![数据模块的核心组件](../img/ch07/7.1/pipeline.png) 18 | :width:`800px` 19 | :label:`pipeline` 20 | 21 | 实现上述的组件只是数据模块的基础,我们还要对如下方面进行重点设计: 22 | 23 | #### 易用性 24 | 25 | AI模型训练/推理过程中涉及到的数据处理非常灵活:一方面,不同的应用场景中数据集类型千差万别,特点各异,在加载数据集时,数据模块要支持图像、文本、音频、视频等多种类型的特定存储格式,还要支持内存、本地磁盘、分布式文件系统以及对象存储系统等多种存储设备类型,模块需要对上述复杂情况下数据加载中的IO差异进行抽象统一,减少用户的学习成本。另一方面,不同的数据类型往往也有着不同的数据处理需求。现有常见机器学习任务中,图像任务常常对图像进行缩放、翻转、模糊化等处理,文本任务需要对文本进行切分、向量化等操作,而语音任务需要对语音进行快速傅立叶变换、混响增强、变频等预处理。为帮助用户解决绝大部分场景下的数据处理需求,数据模块需要支持足够丰富的面向各种类型的数据预处理算子。然而新的算法和数据处理需求在不断快速涌现,我们需要支持用户在数据模块中方便的使用自定义处理算子,以应对数据模块未覆盖到的场景,达到灵活性和高效性的最佳平衡。 26 | 27 | #### 高效性 28 | 29 | 由于GPU/华为昇腾Ascend等常见AI加速器主要面向Tensor数据类型计算,并不具备通用的数据处理能力,现有主流机器学习系统数据模块通常选择使用CPU进行数据流水线的执行。理想情况下,在每个训练迭代步开始之前,数据模块都需要将数据准备好、以减少加速器因为等待数据而阻塞的时间消耗。然而数据流水线中的数据加载和数据预处理常常面临着具有挑战性的I/O性能和CPU计算性能问题,数据模块需要设计具备支持随机读取且具备高读取吞吐率的文件格式来解决数据读取瓶颈问题,同时还需要设计合理的并行架构来高效的执行数据流水线,以解决计算性能问题。为达到高性能的训练吞吐率,主流机器学习系统均采用数据处理与模型计算进行异步执行,以掩盖数据预处理的延迟。 30 | 31 | #### 保序性 32 | 33 | 和常规的数据并行计算任务所不同的是,机器学习模型训练对数据输入顺序敏感。使用随机梯度下降算法训练模型时,通常在每一轮需要按照一种伪随机顺序向模型输入数据,并且在多轮训练(Epoch)中每一轮按照不同的随机顺序向模型输入数据。由于模型最终的参数对输入数据的顺序敏感,为了帮助用户更好的调试和确保不同次实验的可复现性,我们需要在系统中设计相应机制使得数据最终送入模型的顺序由数据混洗组件的数据输出顺序唯一确定,不会由于并行数据变换而带来最终数据模块的数据输出顺序不确定。我们将在后文中对于保序性的要求和具体实现细节展开探讨。 34 | -------------------------------------------------------------------------------- /chapter_data_processing/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | 本章我们围绕着易用性、高效性和保序性三个维度展开研究如何设计实现机器学习系统中的数据预处理模块。在易用性维度我们重点探讨了数据模块的编程模型,通过借鉴历史上优秀的并行数据处理系统的设计经验,我们认为基于描述数据集变换的编程抽象较为适合作为数据模块的编程模型,在具体的系统实现中,我们不仅要在上述的编程模型的基础上提供足够多内置算子方便用户的数据预处理编程,同时还要考虑如何支持用户方便的使用自定义算子。在高效性方面,我们从数据读取和计算两个方面分别介绍了特殊文件格式设计和计算并行架构设计。我们也使用我们在前几章中学习到的模型计算图编译优化技术来优化用户的数据预处理计算图,以进一步的达到更高的数据处理吞吐率。机器学习场景中模型对数据输入顺序敏感,于是衍生出来保序性这一特殊性质,我们在本章中对此进行了分析并通过MindSpore中的Connector的特殊约束实现来展示真实系统实现中如何确保保序性。最后,我们也针对部分情况下单机CPU数据预处理性能的问题,介绍了当前基于异构处理加速的纵向扩展方案,和基于分布式数据预处理的横向扩展方案,我们相信读者学习了本章后能够对机器学习系统中的数据模块有深刻的认知,也对数据模块未来面临的挑战有所了解。 4 | 5 | ## 扩展阅读 6 | 7 | - 流水线粒度并行实现示例建议阅读 [Pytorch DataLoader](https://github.com/pytorch/pytorch/tree/master/torch/utils/data)。 8 | - 算子粒度并行实现示例建议阅读 [MindData](https://gitee.com/mindspore/mindspore/tree/master/mindspore/ccsrc/minddata)。 -------------------------------------------------------------------------------- /chapter_distributed_training/cluster.md: -------------------------------------------------------------------------------- 1 | ## 机器学习集群架构 2 | 3 | 机器学习模型的分布式训练通常会在计算集群(Compute Cluster)中实现。接下来,我们将介绍计算集群的构成,特别是其集群网络的设计。 4 | 5 | ![机器学习集群架构](../img/ch09/ch10-datacentre.png) 6 | :width:`800px` 7 | :label:`ch10-datacentre` 8 | 9 | :numref:`ch10-datacentre` 描述了一个机器学习集群的典型架构。这种集群中会部署大量带有硬件加速器的服务器。每个服务器中往往有多个加速器。为了方便管理服务器,多个服务器会被放置在一个机柜(Rack)中,同时这个机柜会接入一个架顶交换机(Top of Rack Switch)。在架顶交换机满载的情况下,可以通过在架顶交换机间增加骨干交换机(Spine Switch)进一步接入新的机柜。这种连接服务器的拓扑结构往往是一个多层树(Multi-Level Tree)。 10 | 11 | 需要注意的是,在集群中跨机柜通信(Cross-Rack Communication)往往会有网络瓶颈。这是因为集群网络为了便于硬件采购和设备管理,会采用统一规格的网络链路。因此,在架顶交换机到骨干交换机的网络链路常常会形成网络带宽超额认购(Network Bandwidth Oversubscription),即峰值带宽需求会超过 12 | 实际网络带宽。如 :numref:`ch10-datacentre` 的集群内,当服务器1和服务器2利用各自的网络链路(假设10Gb/s)往服务器3发送数据时,架顶交换机1会汇聚2倍数据(即20Gb/s)需要发往骨干交换机1。然而骨干交换机1和架顶交换机1 13 | 之间只有一条网络链路(10Gb/s)。这里,峰值的带宽需求是实际带宽的两倍,因此产生网络超额订购。在实际的机器学习集群中,实际带宽和峰值带宽的比值一般在1:4到1:16之间。因此如果将网络通信限制在机柜内,从而避免网络瓶颈成为了分布式机器学习系统的核心设计需求。 14 | 15 | 那么,在计算集群中训练大型神经网络需要消耗多少网络带宽呢?假设给定一个千亿级别参数的神经网络(比如OpenAI 发布的大型语言模型GPT-3有最多将近1750亿参数),如果用32位浮点数来表达每一个参数,那么每一轮训练迭代(Training Iteration)训练中,一个数据并行模式下的模型副本(Model Replica)则需要生成700GB,即175G $*$ 4 bytes = 700GB,的本地梯度数据。假如有3个模型副本,那么至少需要传输1.4TB,即700GB $*$ $(3-1)$,的梯度数据。这是因为对于$N$个副本,只需传送其中的$N-1$个副本完成计算。当平均梯度计算完成后,需要进一步将其广播(Broadcast)到全部的模型副本(即1.4TB的数据)并更新其中的本地参数,从而确保模型副本不会偏离(Diverge)主模型中的参数。 16 | 17 | 当前的机器学习集群一般使用以太网(Ethernet)构建不同机柜之间的网络。主流的商用以太网链路带宽一般在10Gb/s到25Gb/s之间。这里需要注意的是,网络带宽常用Gb/s为单位,而内存带宽常用GB/s为单位。前者以比特(bit)衡量,后者以字节(byte)衡量。 18 | 19 | 利用以太网传输海量梯度会产生严重的传输延迟。新型机器学习集群(如英伟达的DGX系列机器)往往配置有更快的InfiniBand。单个InfiniBand链路可以提供100Gb/s或200Gb/s的带宽。即使拥有这种高速网络,传输TB级别的本地梯度依然需要大量延迟(即使忽略网络延迟,1TB的数据在200Gb/s的链路上传输也需要至少40s)。InfiniBand的编程接口以远端内存直接读取(Remote Direct Memory Access,RDMA)为核心,提供了高带宽,低延迟的数据读取和写入函数。然而,RDMA的编程接口和传统以太网的TCP/IP的Socket接口有很大不同,为了解决兼容性问题,人们可以用IPoIB (IP-over-InfiniBand)技术。这种技术确保了遗留应用(Legacy Application)可以保持Socket调用,而底层通过IPoIB调用InfiniBand的RDMA接口。 20 | 21 | 为了在服务器内部支持多个加速器(通常2-16个),通行的做法是在服务器内部构建一个异构网络。以 :numref:`ch10-datacentre` 中的服务器1为例,这个服务器放置了两个CPU,CPU之间通过QuickPath Interconnect (QPI)进行通信。而在一个CPU接口(Socket)内,加速器和CPU通过PCIe总线(Bus)互相连接。由于加速器往往采用高带宽内存(High-Bandwidth Memory,HBM)。HBM的带宽(例如英伟达A100的HBM提供了1935 GB/s的带宽)远远超过PCIe的带宽(例如英伟达A100服务器的PCIe 4.0只能提供64GB/s的带宽)。在服务器中,PCIe需要被全部的加速器共享。当多个加速器同时通过PCIe进行数据传输时,PCIe就会成为显著的通信瓶颈。为了解决这个问题,机器学习服务器往往会引入加速器高速互连(Accelerator High-speed Interconnect),例如英伟达A100 GPU的NVLink提供了600 GB/s的带宽,从而绕开PCIe进行高速通信。 -------------------------------------------------------------------------------- /chapter_distributed_training/index.md: -------------------------------------------------------------------------------- 1 | # 分布式训练 2 | 3 | 随着机器学习的进一步发展,科学家们设计出更大型、更多功能的机器学习模型(例如GPT-3)。这种模型含有大量参数和复杂的结构。他们因此需要海量的计算和内存资源。单个机器上有限的资源无法满足训练大型机器学习模型的需求。因此,需要设计分布式训练系统,从而将一个机器学习模型任务拆分成多个子任务,并将子任务分发给多个计算节点,解决资源瓶颈。 4 | 5 | 本章引入分布式机器学习系统的相关概念、设计挑战、系统实现和实例研究。首先讨论分布式训练系统的定义、设计动机和好处。然后进一步讨论常见的分布式训练方法:数据并行、模型并行和流水线并行。在实际中,这些分布式训练方法会被集合通信(Collective Communication)或者参数服务器(Parameter Servers)实现。不同的系统实现具有各自的优势和劣势。 6 | 7 | 本章的学习目标包括: 8 | 9 | - 掌握分布式训练相关系统组件的设计。 10 | 11 | - 掌握常见的分布式训练方法:数据并行、模型并行和流水线并行。 12 | 13 | - 掌握常见的分布式训练框架实现:集合通信和参数服务器。 14 | 15 | 16 | ```toc 17 | :maxdepth: 2 18 | 19 | overview 20 | methods 21 | cluster 22 | collective 23 | parameter_servers 24 | summary 25 | ``` -------------------------------------------------------------------------------- /chapter_distributed_training/overview.md: -------------------------------------------------------------------------------- 1 | ## 系统概述 2 | 3 | ### 设计动机 4 | 5 | 分布式训练系统主要为了解决单节点的算力和内存不足的问题。 6 | 7 | #### 算力不足 8 | 9 | 单处理器的算力不足是促使人们设计分布式训练系统的一个主要原因。一个处理器的算力可以用**每秒钟浮点数操作**(Floating Point Operations Per Second,FLOPS)来衡量。:numref:`ch10-computation-increase`分析了机器学习模型对于算力的需求以及同期处理器所提供算力在过去数年中变化。其中,用千万亿运算次数/秒—天(Petaflop/s—day )这一指标来衡量算力。这个指标等价于每秒$10^{15}$次神经网络操作执行一天,也就是总共大约$10^{20}$次计算操作。如图所示,根据摩尔定律(Moore's Law),中央处理器的算力每18个月增长2倍。虽然计算加速卡(如GPU和TPU)针对机器学习计算提供了大量的算力。这些加速卡的发展最终也受限于摩尔定律,增长速度停留在每18个月2倍。而与此同时,机器学习模型正在快速发展。短短数年,机器学习模型从仅能识别有限物体的AlexNet,一路发展到在复杂任务中打败人类的AlphaStar。这期间,模型对于算力需求每18个月增长了56倍。解决处理器性能和算力需求之间鸿沟的关键就在于利用分布式计算。通过大型数据中心和云计算设施,可以快速获取大量的处理器。通过分布式训练系统有效管理这些处理器,可以实现算力的快速增长,从而持续满足模型的需求。 10 | 11 | ![对比机器学习模型参数量增长和计算硬件的算力增长](../img/ch09/ch10-computation-increase.png) 12 | :width:`800px` 13 | :label:`ch10-computation-increase` 14 | 15 | #### 内存不足 16 | 17 | 训练机器学习模型需要大量内存。假设一个大型神经网络模型具有1000亿的参数,每个参数都由一个32位浮点数(4个字节)表达,存储模型参数就需要400GB的内存。在实际中,我们需要更多内存来存储激活值和梯度。假设激活值和梯度也用32位浮点数表达,那么其各自至少需要400GB内存,总的内存需求就会超过1200GB(即1.2TB)。而如今的硬件加速卡(如NVIDIA A100)仅能提供最高80GB的内存。单卡内存空间的增长受到硬件规格、散热和成本等诸多因素的影响,难以进一步快速增长。因此,我们需要分布式训练系统来同时使用数百个训练加速卡,从而为千亿级别的模型提供所需的TB级别的内存。 18 | 19 | ### 系统架构 20 | 21 | 为了方便获得大量用于分布式训练的服务器,人们往往依靠云计算数据中心。一个数据中心管理着数百个集群,每个集群可能有几百到数千个服务器。通过申请其中的数十台服务器,这些服务器进一步通过分布式训练系统进行管理,并行完成机器学习模型的训练任务。 22 | 23 | ![单节点计算和多节点分布式计算](../img/ch09/ch10-single-vs-multi.png) 24 | :width:`800px` 25 | :label:`ch10-single-vs-multi` 26 | 27 | 为了确保分布式训练系统的高效运行,需要首先估计系统计算任务的计算和内存用量。假如某个任务成为了瓶颈,系统会切分输入数据,从而将一个任务拆分成多个子任务。子任务进一步分发给多个计算节点并行完成。:numref:`ch10-single-vs-multi`描述了这一过程。一个模型训练任务(Model Training Job)往往会有一组数据(如训练样本)或者任务(如算子)作为输入,利用一个计算节点(如GPU)生成一组输出(如梯度)。分布式执行一般具有三个步骤:第一步将输入进行切分;第二步将每个输入部分会分发给不同的计算节点,实现并行计算;第三步将每个计算节点的输出进行合并,最终得到和单节点等价的计算结果。这种首先切分,然后并行,最后合并的模式,本质上实现了分而治之(Divide-and-Conquer)的方法:由于每个计算节点只需要负责更小的子任务,因此其可以更快速地完成计算,最终实现对整个计算过程的加速。 28 | 29 | ### 用户益处 30 | 31 | 通过使用分布式训练系统可以获得以下几个优点: 32 | 33 | - **提升系统性能**:使用分布式训练,往往可以带来训练性能的巨大提升。一个分布式训练系统一般用“到达目标精度所需的时间”(Time-to-Accuracy)这个指标来衡量系统性能。这个指标由两个参数决定: (1)完成一个数据周期的时间,和(2)完成一个数据周期后模型所提升的精度。通过持续增加并行处理节点,可以将数据周期的完成时间不断变短,最终显著减少到达目标精度所需的时间。 34 | 35 | - **减少成本,体现经济性**:使用分布式训练也可以进一步减少模型训练的成本。受限于单节点散热的上限,单节点的算力越高,其所需的散热硬件成本也更高。因此,在提供同等算力的条件下,组合多个计算节点是一个更加经济高效的方式。这促使云服务商(如亚马逊和微软等)更加注重给用户提供成本高效的分布式机器学习系统。 36 | 37 | - **防范硬件故障**:分布式训练系统同时能有效提升防范硬件故障的能力。机器学习训练集群往往由商用硬件(Commodity Hardware)组成,这类硬件(例如磁盘和网卡)运行一定时间就会产生故障。而仅使用单个机器进行训练,一个机器的故障就会造成模型训练任务的失败。通过将该模型训练任务交由多个机器共同完成,即使一个机器出故障,也可以通过将该机器上相应的计算子任务转移给其余机器,继续完成训练,从而避免训练任务的失败。 -------------------------------------------------------------------------------- /chapter_distributed_training/parameter_servers.md: -------------------------------------------------------------------------------- 1 | ## 参数服务器 2 | 3 | 下面介绍另一种常见的分布式训练系统:参数服务器。不同的机器学习框架以不同方式提供参数服务器的实现。TensorFlow和MindSpore内置了参数服务器的实现。PyTorch需要用户使用RPC接口自行实现。同时,我们也有参数服务器的第三方实现,如PS-Lite。 4 | 5 | ### 系统架构 6 | 7 | 不同于基于集合通信实现的机器学习系统,参数服务器系统中的服务器会被分配两种角色:训练服务器和参数服务器。其中参数服务器需要提供充足内存资源和通信资源,训练服务器需要提供大量的计算资源(如硬件加速器)。 :numref:`ch10-parameter-servers` 描述了带有参数服务器的机器学习集群。这个集群中含有两个训练服务器和两个参数服务器。 8 | 假设我们有一个模型,可以切分为两个参数分区。每个分区被分配给一个参数服务器负责参数同步。 9 | 在训练的过程中,每个训练服务器都会有完整的模型,根据本地的训练数据集切片(Dataset Shard)训练出梯度。这个梯度会被推送(Push)到各自参数服务器。参数服务器等到两个训练服务器都完成梯度推送,开始计算平均梯度,更新参数。它们然后通知训练服务器来拉取(Pull)最新的参数,开始下一轮训练迭代。 10 | 11 | ![参数服务器架构](../img/ch09/ch10-parameter-servers.png) 12 | :width:`800px` 13 | :label:`ch10-parameter-servers` 14 | 15 | ### 异步训练 16 | 17 | 参数服务器的一个核心作用是可以处理分布式训练服务器中出现的落后者(Straggler)。在之前的讨论中,在每一轮训练结束后,训练服务器都需要计算平均梯度对每一个模型副本进行更新,从而保证下一轮训练开始前,全部模型副本参数的一致性,这种对于参数一致性的确保一般被称为同步训练(Synchronous Training)。同步训练一般有助于训练系统达到更好的模型精度,但是当系统规模变大,往往会观察到落后者服务器的出现。落后者出现的原因很多。常见的原因包括:落后者设备可能和其他设备不在同一个机柜中,因此落后者的通信带宽显著小于其他设备。另外,落后者设备也可能和其他进程共享本地的服务器计算和通信资源,形成资源竞争,从而降低了性能。 18 | 19 | 落后者对于基于AllReduce的同步训练系统的性能有显著影响,这是因为AllReduce让全部节点参与到平均梯度的计算和通信中,而每个节点负责等量的数据。因此一个落后者的出现,都会让整个AllReduce操作延迟完成。为了解决这个问题,人们常使用参数服务器同步梯度。一种常见的设计是:训练服务器训练出梯度后,会把本地梯度全部推送到参数服务器。参数服务器在等到一定训练服务器(例如90\%的训练服务器)的梯度后,就开始计算平均梯度。这样可以确保平均梯度的计算不会被落后者的出现延误。计算好的平均梯度马上推送给全部训练服务器,开始下一轮训练。 20 | 21 | 解决落后者的另一种常见做法是利用参数服务器实现异步训练(Asynchronous Training)。在一个异步训练系统中,每个训练服务器在训练开始时,有相同的模型参数副本。在训练中,它们计算出梯度后会马上将梯度推送到参数服务器,参数服务器将推送的梯度立刻用于更新参数,并通知训练服务器立刻来拉取最新的参数。在这个过程中,不同的训练服务器很可能会使用不同版本的模型参数进行梯度计算,这种做法可能会伤害模型的精度,但它同时让不同训练服务器可以按照各自的运算速度推送和拉取参数,而无须等待同伴,因此避免了落后者对于整个集群性能的影响。 22 | 23 | ### 数据副本 24 | 25 | 在参数服务器的实际部署中,人们往往需要解决数据热点问题。互联网数据往往符合幂律概率(Power-Law Distribution),这会导致部分参数在训练过程中被访问的次数会显著高于其他参数。例如,热门商品的嵌入项(Embedding Item)被训练服务器拉取的次数就会远远高于非热门商品。因此,存储了热门数据的参数服务器所承受的数据拉取和推送请求会远远高于其他参数服务器,因此形成数据热点,伤害了系统的可扩展性。 26 | 27 | 利用数据副本的另一个作用是增加系统的鲁棒性。当一个参数服务器出现故障,其所负责的参数将不可用,从而影响了整体系统的可用性。通过维护多个参数副本,当一个参数服务器故障时,系统可以将参数请求导向其他副本,同时在后台恢复故障的参数服务器,确保系统的可用性不受影响。 28 | 29 | 解决参数服务器故障和数据热点问题的常用技术是构建模型主从复制(Leader-Follower Replication)。一份参数在多个机器上拥有副本,并指定其中一个副本作为主副本(Leader Replica)。训练服务器的所有更新操作都向主副本写入,并同步至全部从副本(Follower Replica)。如何取得共识并确定哪一个副本是主副本是分布式系统领域一个经典问题,对该问题已经有了相当多的成熟算法,例如Paxos和Raft。此外,主副本上的更新如何复制到从副本上也是分布式系统领域的经典共识问题。通常系统设计者需要在可用性(Availability)和一致性(Consistency)之间做出取舍。如果参数服务器副本间采用强一致性(Strong Consistency)的复制协议(Replication Protocol),例如链式复制(Chain Replication),则可能导致训练服务器的推送请求失败,即参数服务器不可用。反之,如果参数服务器采用弱一致性(Weak Consistency)的复制协议,则可能导致副本间存储的参数不一致。 -------------------------------------------------------------------------------- /chapter_distributed_training/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 大型机器学习模型的出现带来了对于算力和内存需求的快速增长,催生了分布式训练系统的出现。 4 | 5 | - 分布式训练系统的设计往往遵循“分而治之”的设计思路。 6 | 7 | - 利用分布式训练系统,人们可以显著提升训练性能,体现经济性,并且帮助防范硬件故障。 8 | 9 | - 分布式训练系统可以通过数据并行增加设备来提升算力。 10 | 11 | - 当单节点内存不足时,可以通过模型并行解决单设备内存不足。模型并行有两种实现方式:算子内并行和算子间并行。 12 | 13 | - 大型模型并行系统容易出现设备使用气泡,而这种气泡可以通过流水线并行解决。 14 | 15 | - 分布式训练系统往往运行在计算集群之中,集群网络无法提供充足的网络带宽来传输大量训练中生成的梯度。 16 | 17 | - 为了提供海量的通信带宽,机器学习集群拥有异构的高性能网络,包括以太网、加速器高速互连技术NVLink和高带宽网络InfiniBand。 18 | 19 | - 为了解决单节点瓶颈,可以使用AllReduce算法来分摊梯度聚合过程中产生的计算和通信操作,同时实现负载均衡。 20 | 21 | - 参数服务器可以帮助实现灵活的梯度同步和异步训练,从而防范集群中可能出现的落后者服务器。 22 | 23 | - 参数服务器常用数据副本技术解决数据热点问题和防范硬件故障。 24 | 25 | 26 | ## 拓展阅读 27 | 28 | - [分布式机器学习系统综述](https://dl.acm.org/doi/abs/10.1145/3377454) 29 | 30 | - [利用集合通信支持并行训练的实践:Horovod](https://arxiv.org/abs/1802.05799) 31 | 32 | - [流水线并行的实践:gPipe](https://arxiv.org/abs/1811.06965) 33 | 34 | - [利用数据并行在大型数据集上高效训练深度学习模型](https://arxiv.org/abs/1706.02677) -------------------------------------------------------------------------------- /chapter_explainable_AI/index.md: -------------------------------------------------------------------------------- 1 | # 可解释性AI系统 2 | 3 | 近10年来,籍由算力与数据规模的性价比突破临界点,以深度神经网络为代表的联结主义模型架构及统计学习范式(以后简称深度学习)在特征表征能力上取得了跨越级别的突破,大大推动了人工智能的发展,在很多场景中达到令人难以置信的效果。比如:人脸识别准确率达到97%以上;谷歌智能语音助手回答正确率,在2019年的测试中达到92.9%。在这些典型场景下,深度学习在智能表现上的性能已经超过了普通人类(甚至专家),从而到了撬动技术更替的临界点。在过去几年间,在某些商业逻辑对技术友好,或者伦理法规暂时稀缺的领域,如安防、实时调度、流程优化、竞技博弈、信息流分发等,人工智能和深度学习取得了技术和商业上快速突破。 4 | 5 | 食髓知味,技术发展的甜头自然每个领域都不愿放过。而当对深度学习的商业化运用来到某些对技术敏感、与人的生存或安全关系紧密的领域,如自动驾驶、金融、医疗和司法等高风险应用场景时,原有的商业逻辑在进行技术更替的过程中就会遇到阻力,从而导致商业化变现速度的减缓甚至失败。究其原因,以上场景的商业逻辑及背后伦理法规的中枢之一是稳定的、可追踪的责任明晰与责任分发;而深度学习得到的模型是个黑盒,我们无法从模型的结构或权重中获取模型行为的任何信息,从而使这些场景下责任追踪和分发的中枢无法复用,导致人工智能在业务应用中遇到技术上和结构上的困难。此外,模型的可解释性问题也引起了国家层面的关注,相关机构对此推出了相关的政策和法规。 6 | 7 | 因此,从商业推广层面以及从法规层面,我们都需要打开黑盒模型,对模型进行解释,可解释AI正是解决该类问题的技术。 8 | 9 | 本章的学习目标包括: 10 | 11 | - 掌握可解释AI的目标和应用场景 12 | 13 | - 掌握常见的可解释AI方法类型及其对应的典型方法 14 | 15 | - 思考可解释AI方法的未来发展 16 | 17 | ```toc 18 | :maxdepth: 2 19 | 20 | explainable_ai 21 | ``` 22 | -------------------------------------------------------------------------------- /chapter_federated_learning/horizontal_fl.md: -------------------------------------------------------------------------------- 1 | ## 横向联邦学习 2 | 3 | ### 云云场景中的横向联邦 4 | 5 | 在横向联邦学习系统中,具有相同数据结构的多个参与者通过云服务器协同建立机器学习模型。一个典型的假设是参与者是诚实的,而服务器是诚实但好奇的,因此不允许任何参与者向服务器泄漏原始的梯度信息。这种系统的训练过程通常包括以下四个步骤: 6 | 7 | ①:参与者在本地计算训练梯度,使用加密、差分隐私或秘密共享技术掩码所选梯度,并将掩码后的结果发送到服务器。 8 | 9 | ②:服务器执行安全聚合,不了解任何参与者的梯度信息。 10 | 11 | ③:服务器将汇总后的结果发送给参与者。 12 | 13 | ④:参与者用解密的梯度更新他们各自的模型。 14 | 15 | 和传统分布式学习相比,联邦学习存在训练结点不稳定和通信代价大的难点。这些难点导致了联邦学习无法和传统分布式学习一样:在每次单步训练之后,同步不同训练结点上的权重。为了提高计算通信比并降低频繁通信带来的高能耗,谷歌公司在2017年 :cite:`fedavg`提出了联邦平均算法(Federated Averaging,FedAvg)。 :numfef:`ch10-federated-learning-fedavg`展示了FedAvg的整体流程。在每轮训练过程中,客户端进行了多次单步训练。然后服务端聚合多个客户端的权重,并取加权平均。 16 | 17 | ![联邦平均算法](../img/ch10/ch10-federated-learning-fedavg.png) 18 | :width:`800px` 19 | :label:`ch10-federated-learning-fedavg` 20 | 21 | ### 端云场景中的横向联邦 22 | 23 | 端云联邦学习的总体流程和云云联邦学习一样,但端云联邦学习面临的难点还包括以下三个方面: 24 | 25 | 1.高昂的通信代价。和云云联邦学习不同之处,端云联邦学习的通信开销主要在于单次的通信量,而云云联邦学习的开销主要在于通信的频率。在端云联邦学习场景中,通常的通信网络可能是WLAN或移动数据,网络通信速度可能比本地计算慢许多个数量级,这就造成高昂的通信代价成为了联邦学习的关键瓶颈。 26 | 27 | 2.系统异质性。由于客户端设备硬件条件(CPU、内存)、网络连接(3G、4G、5G、WIFI)和电源(电池电量)的变化,联邦学习网络中每个设备的存储、计算和通信能力都有可能不同。网络和设备本身的限制可能导致某一时间仅有一部分设备处于活动状态。此外,设备还会出现没电、网络无法接入等突发状况,导致瞬时无法连通。这种异质性的系统架构影响了联邦学习整体策略的制定。 28 | 29 | 3.隐私问题。由于端云联邦学习的客户端无法参与每一轮迭代,因此在数据隐私保护上的难度高于其他的分布式学习方法。而且,在联邦学习过程中,端云传递模型的更新信息还存在向第三方或中央服务器暴露敏感信息的风险。隐私保护成为端云联邦学习需要重点考虑的问题。 30 | 31 | 为了解决端云联邦学习带来的挑战,MindSpore Federated设计了分布式FL-Server架构。系统由调度器模块、服务器模块和客户端模块三个部分组成,其系统架构如 :numref:`ch10-federated-learning-architecture`所示。各个模块的功能说明: 32 | 33 | - 联邦学习调度器: 34 | 35 | 联邦学习调度器(FL-Scheduler)协助集群组网,并负责管理面任务的下发。 36 | 37 | - 联邦学习服务器: 38 | 39 | 联邦学习服务器(FL-Server)提供客户端选择、限时通信、分布式联邦聚合功能。FL-Server需要具备支持端云千万台设备的能力以及支持边缘服务器的接入和安全处理的逻辑。 40 | 41 | - 联邦学习客户端: 42 | 43 | 联邦学习客户端(FL-Client)负责本地数据训练,并在和FL-Server进行通信时,对上传权重进行安全加密。 44 | 45 | ![联邦学习系统架构图](../img/ch10/ch10-federated-learning-architecture.svg) 46 | 47 | :label:`ch10-federated-learning-architecture` 48 | 49 | 此外,MindSpore Federated针对端云联邦学习设计了出四大特性: 50 | 51 | 1.限时通信:在FL-Server和FL-Client建立连接后,启动全局的计时器和计数器。当预先设定的时间窗口内的FL-Server接收到FL-Client训练后的模型参数满足初始接入的所有FL-Client的一定比例后,就可以进行聚合。若时间窗内没有达到比例阈值,则进入下一轮迭代。保证即使有海量FL-Client接入的情况下,也不会由于个别FL-Client训练时间过长或掉线导致的整个联邦学习过程卡死。 52 | 53 | 2.松耦合组网:使用FL-Server集群。每个FL-Server接收和下发权重给部分FL-Client,减少单个FL-Server的带宽压力。此外,支持FL-Client以松散的方式接入。任意FL-Client的中途退出都不会影响全局任务,并且FL-Client在任意时刻访问任意FL-Server都能获得训练所需的全量数据。 54 | 55 | 3.加密模块:MindSpore Federated为了防止模型梯度的泄露,部署了多种加密算法:本地差分隐私(Local Differential Privacy,LDP)、基于多方安全计算(MPC)的安全聚合算法和华为自研的基于符号的维度选择差分隐私算法(Sign-based Dimension Selection,SignDS)。 56 | 57 | 4.通信压缩模块:MindSpore Federated分别在FL-Server下发模型参数和FL-Client上传模型参数时,使用量化和稀疏等手段将权重压缩编码成较小的数据格式,并在对端将压缩编码后的数据解码为原始的数据。 58 | -------------------------------------------------------------------------------- /chapter_federated_learning/index.md: -------------------------------------------------------------------------------- 1 | # 联邦学习系统 2 | 3 | 在本章中,我们介绍深度学习的一个重要分支——联邦学习及其在系统方面的知识。本章的学习目标包括: 4 | 5 | - 掌握联邦学习基本定义,并了解现有主流联邦开源框架。 6 | - 了解横向联邦学习算法。 7 | - 了解纵向联邦学习算法。 8 | - 了解联邦学习加密算法。 9 | - 了解联邦学习前沿算法和未来研究方向。 10 | 11 | ```toc 12 | :maxdepth: 2 13 | 14 | overview 15 | horizontal_fl 16 | vertical_fl 17 | privacy_encryption_algorithm 18 | outlook 19 | summary 20 | ``` -------------------------------------------------------------------------------- /chapter_federated_learning/outlook.md: -------------------------------------------------------------------------------- 1 | ## 展望 2 | 3 | 为了实现联邦学习的大规模商用,我们仍然需要做许多的研究工作。比如我们无法查看联邦学习的分布式化的数据,那就很难选择模型的超参数以及设定优化器,只能采用一些基于模拟的方案来调测模型;比如用于移动设备时,单用户的标签数据很少,甚至无法获取数据的标签信息,联邦学习如何用于无监督学习;比如由于参与方的数据分布不一致,训练同一个全局模型,很难评价模型对于每个参与方的好坏;比如数据一直是公司的核心资产,不同的公司一直在致力于收集数据和创造数据孤岛,如何有效地激励公司或者机构参与联邦学习的系统中来。下面将介绍一些MindSpore Federated在进行的一些尝试和业界的相关工作。 4 | 5 | **异构场景下的联邦学习** 6 | 7 | 之前探讨的横向联邦学习和纵向联邦学习都是让不同的参与方共同建立一个共享的机器学习模型。然而,企业级联邦学习框架往往需要适应多种异构场景,如数据异构(不同客户端数据规模以及分布不一致),设备异构(不同客户端设备计算能力,通信效率不一致),以及模型异构(不同本地客户端模型学到的特征不一致)。 8 | 9 | 比较主流的两种联邦学习异构场景下的工作: 10 | 11 | 1)对异构数据具有高度鲁棒性的本地模型个性化联邦学习策略: 12 | 13 | 联邦学习训练的是一个全局模型,基于所有数据得到一个全局最优解,但是不同参与方的数据量和分布都是不同的,很多场景下全局模型无法在把握整体的同时又照顾到这种差异。当某一方的数据和整体偏离比较大时,联邦学习的效果确实有可能不如本地训练的效果。那么如何在所有参与方总体的收益最大化的同时,让个体的收益也能够最大化,这就是个性化联邦学习。 14 | 15 | 个性化联邦学习并不要求所有参与方最终使用的模型必须是一样的,比如允许每个参与方在参与联邦学习之后,根据自己的数据对模型进行微调,从而生成本方独特的个性化模型。在进行个性化微调之后,往往模型在本地测试集上的效果会更好。在这种方式下,不同参与方的模型结构是一样的,但是模型参数会有所不同。还有一些方案,是让所有的参与方拥有同样的特征提取层,但是任务分类层不同。还有的思路是将知识蒸馏引入联邦学习中,将联邦学习的全局模型作为教师模型,将个性化模型作为学生模型,可以缓解个性化过程中的过拟合问题。 16 | 17 | 2)对于异构模型进行模型聚合的策略研究: 18 | 19 | 一般在FedAvg的联邦聚合范式下,本地迭代训练次数越少、聚合地越频繁,模型收敛精度会越好,尤其是在不同参与客户端的数据是非IID情况下。但是聚合会带来通信成本开销,联邦学习存在通信成本与模型精度的Trade-Off。因此很多研究者聚焦于如何设计自适应聚合方案,要求在给定训练时间开销的前提下,找到本地更新和全局通信之间的最佳平衡,令全局模型的泛化误差最小。 20 | 21 | **通信效率提升** 22 | 23 | 在联邦学习流程中,每一个全局训练轮次里,每个参与方都需要给服务端发送完整的参数。然后服务端将聚合后的参数下发。现代的深度学习网络动辄有数百万甚至更大量级的参数,如此多的参数传输将会带来巨大的通信开销。为了降低通信开销,MindSpore Federated采取了一些改善通信效率的方法: 24 | 25 | 1)智能调频策略:通过改变全局模型聚合的轮次来提高联邦学习效率,减少训练任务达到收敛的通信开销。一种直觉是在联邦学习流程的初期,不同参与方的参数变化较为一致,因此设置较小的聚合频率,可以减少通信成本;在联邦学习流程的后期,不同参与方的参数变化较为不一致,因此设置较大的聚合频率,可以使得模型快速收敛。 26 | 27 | 2)通信压缩方案:对权重差进行量化以及稀疏化操作,即每次通信仅上传一小部分量化后的权重差值。之所以选择权重差做量化和稀疏,是因为它比权重值的分布更易拟合,而且稀疏性更高。量化就是将float32的数据类型映射到int8甚至更低比特表示的数值上,一方面降低存储和通信开销,另一方面可以更好地采用一些压缩编码方式进行传输(如哈夫曼编码、有限状态熵编码等)。比较常用的稀疏化方法有Top-K稀疏,即按梯度的绝对值从小到大排序,每轮只上传前k个参数。通信压缩方案一般是精度有损的,如何选取合适的k是一个有挑战性的问题。 28 | 29 | **联邦生态** 30 | 31 | 在前面的章节中,我们介绍了面向隐私保护的联邦学习领域的一些技术与实践,然而随着探索地更加深入,联邦学习领域也变得更具包容性,它涵盖了机器学习、模型压缩部署、信息安全、加密算法、博弈论等等。随着越来越多的公司、高校和机构参与进来,现在的联邦学习已经不仅仅是一种技术解决方案,还是一个隐私保护的生态系统,比如不同的参与方希望以可持续的方式加入联邦学习流程,如何设计激励机制以确保利润可以相对公平地被各参与方共享,同时对于恶意的实施攻击或者破坏行为的参与方进行有效遏制。 32 | 33 | 另外,随着用户数据隐私保护和合理使用的法律法规越来越多的被推出,制定联邦学习的技术标准显得愈加重要,这一标准能够在法律监管部门和技术开发人员之间建立一座桥梁,让企业知道采用何种技术,能够在合乎法规的同时更好地进行信息的共享。 34 | 35 | 2020年底正式出版推行了由IEEE 标准委员会通过的联邦学习国际标准(IEEE P3652.1),该标准旨在提供一个搭建联邦学习的体系架构和应用的指导方针,主要内容包括:联邦学习的描述和定义、场景需求分类和安全测评、联邦学习个性指标的评估如何量化、联合管控的需求。这也是国际上首个针对人工智能协同技术框架订立的标准,标志着联邦学习开启大规模工业化应用的新篇章。 36 | -------------------------------------------------------------------------------- /chapter_federated_learning/overview.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | 随着人工智能的飞速发展,大规模和高质量的数据对模型的效果和用户的体验都变得越来越重要。与此同时,数据的利用率成为了制约了人工智能的进一步发展的瓶颈。隐私、监管和工程等问题造成了设备与设备之间的数据不能共享,进而导致了数据孤岛问题的出现。为了解决这一难题,联邦学习(Federated Learning,FL)应运而生。联邦学习的概念最早在2016年被提了出来。在满足用户隐私保护、数据安全和政府法规的要求下,联邦学习能有效地使用多方机构的数据进行机器学习建模。 4 | 5 | ### 定义 6 | 7 | 联邦学习的核心是数据不动,模型动。显然,若是将数据从各方集中在一起,无法保证对用户隐私的保护,且不符合相关法律法规。联邦学习让模型在各个数据方“移动”,这样就可以达到数据不出端即可建模的效果。在联邦学习中,各方数据都保留在本地,通过(在中心服务器上)交换加密的参数或其他信息来建立机器学习模型。 8 | 9 | ### 应用场景 10 | 11 | 在实际的应用场景中,根据样本和特征的重叠情况,联邦学习可以被分为横向联邦学习(样本不同,特征重叠),纵向联邦学习(特征不同,样本重叠)和联邦迁移学习(样本和特征都不重叠)。 12 | 13 | **横向联邦学习**适用于不同参与方拥有的特征相同、但参与的个体不同的场景。比如,在广告推荐场景中,算法开发人员使用不同手机用户的相同特征(点击次数、停留时间或使用频次等)的数据来建立模型。因为这些特征数据不能出端,横向联邦学习被用来联合多用户的特征数据来构建模型。 14 | 15 | **纵向联邦学习**适用于样本重叠多、特征重叠少的场景。比如,有两个不同机构,一家是保险公司,另一家是医院。它们的用户群体很有可能包含该地的大部分居民。它们两方的用户交集可能较大。由于保险公司记录的是用户的收支行为与信用评级,而医院则拥有用户的疾病与购药记录,因此它们的用户特征交集较小。纵向联邦学习就是将这些不同特征在加密的状态下加以聚合,以增强模型能力的方法。 16 | 17 | **联邦迁移学习**的核心是找到源领域和目标领域之间的相似性。比如有两个不同机构,一家是位于中国的银行,另一家是位于美国的电商。由于受到地域限制,这两家机构的用户群体交集很小。同时,由于机构类型的不同,二者的数据特征也只有小部分重合。在这种情况下,要想进行有效的联邦学习,就必须引入迁移学习。联邦迁移学习可以解决单边数据规模小和标签样本少的问题,并提升模型的效果。 18 | 19 | ### 部署场景 20 | 21 | 联邦学习和参数服务器(数据中心分布式学习)架构非常相似,都是采用中心化的服务器和分散的客户端去构建同一个机器学习模型。此外,根据部署场景的不同,联邦学习还可以细分为跨组织(Cross-silo)与跨设备(Cross-device)联邦学习。一般而言,跨组织联邦学习的用户一般是企业、机构单位级别的,而跨设备联邦学习针对的则是便携式电子设备、移动端设备等。 :numref:`ch10-federated-learning-different-connection`展示了三者的区别和联系: 22 | 23 | ![数据中心分布式训练、跨组织和跨设备联邦学习的区别和联系](../img/ch10/ch10-federated-learning-different-connection.png) 24 | :width:`800px` 25 | :label:`ch10-federated-learning-different-connection` 26 | 27 | ### 常用框架 28 | 29 | 随着用户和开发人员对联邦学习技术的需求不断增长,联邦学习工具和框架的数量也越来越多。下面将介绍一些主流的联邦学习框架。 30 | 31 | [TFF](https://www.tensorflow.org/federated) (TensorFlow Federated)是谷歌牵头开发的联邦学习开源框架,用于在分散数据上进行机器学习和其他计算。TFF的开发是为了促进联邦学习的开放研究和实验。在许多参与的客户中训练共享的全局模型,这些客户将其训练数据保存在本地。例如,联邦学习已被用于训练移动键盘的预测模型,而无需将敏感的键入数据上载到服务器。 32 | 33 | [PaddleFL](https://paddlefl.readthedocs.io/en/latest/index.html)是百度提出的一个基于PaddlePaddle的开源联邦学习框架。研究人员可以很轻松地用PaddleFL复制和比较不同的联邦学习算法,开发人员也比较容易在大规模分布式集群中部署PaddleFL联邦学习系统。PaddleFL提供很多种联邦学习策略(横向联邦学习、纵向联邦学习)及其在计算机视觉、自然语言处理、推荐算法等领域的应用。此外,PaddleFL还提供传统机器学习训练策略的应用,例如多任务学习、联邦学习环境下的迁移学习。依靠着PaddlePaddle的大规模分布式训练和Kubernetes对训练任务的弹性调度能力,PaddleFL可以基于全栈开源软件轻松地部署。 34 | 35 | [FATE](https://fate.fedai.org) (Federated AI Technology Enabler)由微众银行提出,是全球首个联邦学习工业级开源框架,可以让企业和机构在保证数据安全和数据隐私不泄露的前提下进行数据协作。 FATE项目使用多方安全计算 (Secure Multi-Party Computation,MPC) 以及同态加密 (Homomorphic Encryption,HE) 技术构建底层安全计算协议,以此支持不同种类的机器学习的安全计算,包括逻辑回归、基于树的算法、深度学习和迁移学习等。 FATE于2019年2月首次对外开源,并成立FATE社区。社区成员包含国内主要云计算和金融服务企业。 36 | 37 | [FedML](https://FedML.ai)是一个南加利福尼亚大学(University of Southern California,USC)牵头提出的联邦学习开源研究和基准库,它有助于开发新的联合学习算法和公平的性能比较。FedML支持三种计算范式(分布式训练、移动设备上训练和独立模拟),供用户在不同的系统环境中进行实验。FedML还通过灵活和通用的API设计和参考基线实现并促进了多样化的算法研究。为了使各联邦学习算法可以进行公平比较,FedML设置了全面的基准数据集,其中包括非独立同分布(Independent Identically Distribution,IID)数据集。 38 | 39 | [PySyft](https://openmined.github.io/PySyft/index.html)是伦敦大学学院(University College London,UCL)、DeepMind和OpenMined发布的安全和隐私深度学习Python库,包括联邦学习、差分隐私和多方学习。PySyft使用差分隐私和加密计算(MPC和HE)将私有数据与模型训练解耦。 40 | 41 | [Fedlearner](https://github.com/bytedance/fedlearner)是字节跳动提出的纵向联邦学习框架,它允许对分布在机构之间的数据进行联合建模。Fedlearner附带了用于集群管理、作业管理、作业监控和网络代理的周围基础架构。Fedlearner采用云原生部署方案,并将数据存放在HDFS中。Fedlearner通过Kubernetes管理和拉起任务。每个Fedlearner的参与双方需要同时通过Kubernetes拉起训练任务,并通过Master节点统一管理多个训练任务,以及通过Worker实现通信。 42 | 43 | [OpenFL](https://openfl.readthedocs.io/en/latest/index.html)是英特尔提出的用于联邦学习的Python框架。OpenFL旨在成为数据科学家的灵活、可扩展和易于学习的工具。 44 | 45 | [Flower](https://flower.dev)是剑桥大学发布的联邦学习开源系统,主要针对在大规模、异质化设备上部署联邦学习算法的应用场景进行优化。 46 | 47 | [MindSpore Fedrated](https://www.mindspore.cn/en)是华为提出的一款开源联邦学习框架,支持千万级无状态终端设备商用化部署,在用户数据留存在本地的情况下,使能全场景智能应用。MindSpore Federated专注于大规模参与方的横向联邦学习的应用场景,使参与联邦学习的各用户在不共享本地数据的前提下共建AI模型。MindSpore Federated主要解决隐私安全、大规模联邦聚合、半监督联邦学习、通信压缩和跨平台部署等联邦学习在工业场景部署的难点。 48 | -------------------------------------------------------------------------------- /chapter_federated_learning/summary.md: -------------------------------------------------------------------------------- 1 | ## 小结 2 | 3 | 在这一章,我们简单介绍了联邦学习的背景、系统架构、联邦平均算法、隐私加密算法以及实际部署时的挑战。联邦学习是一个新起步的人工智能算法,可以在“数据保护”与“数据孤岛”这两大约束条件下,建立有效的机器学习模型。此外,由于联邦学习场景的特殊性(端侧数据不上传、安全隐私要求高和数据非独立同分布等特点),使得系统和算法的开发难度更高:如何平衡计算和通讯的开销,如何保证模型不会泄露隐私,算法如何在非独立同分布场景下收敛。这些难点都需要开发人员对实际的联邦学习场景有更深刻的认识。 4 | -------------------------------------------------------------------------------- /chapter_federated_learning/vertical_fl.md: -------------------------------------------------------------------------------- 1 | ## 纵向联邦学习 2 | 3 | 现在我们介绍另一种联邦学习算法:纵向联邦学习(Vertical Federated Learning)。纵向联邦学习的参与方拥有相同样本空间、不同特征空间的数据,通过共有样本数据进行安全联合建模,在金融、广告等领域拥有广泛的应用场景。和横向联邦学习相比,纵向联邦学习的参与方之间需要协同完成数据求交集、模型联合训练和模型联合推理。并且,参与方越多,纵向联邦学习系统的复杂度就越高。 4 | 5 | 下面以企业A和企业B两方为例来介绍纵向联邦学习的基本架构和流程。假设企业A有特征数据和标签数据,可以独立建模;企业B有特征数据,缺乏标签数据,因此无法独立建模。由于隐私法规和行业规范等原因,两个企业之间的数据无法直接互通。企业A和企业B可采用纵向联邦学习解决方案进行合作,数据不出本地,使用双方共同样本数据进行联合建模和训练。最终双方都能获得一个更强大的模型。 6 | 7 | ### 纵向联邦架构 8 | 9 | ![纵向联邦两方架构](../img/ch10/ch10-federated-learning-vfl-arch.svg) 10 | :width:`800px` 11 | :label:`federated-learning-vfl-arch` 12 | 13 | 纵向联邦学习系统中的模型训练一般分为如下阶段: 14 | - 样本对齐:首先对齐企业A和企业B中具有相同ID(Identification)的样本数据。在数据对齐阶段,系统会采用加密算法对数据进行保护,确保任何一方的用户数据不会暴露。 15 | - 联合训练:在确定企业A和企业B共有用户数据后,可以使用这些共有的数据来协同训练一个业务模型。模型训练过程中,模型参数信息以加密方式进行传递。已训练好的联邦学习模型可以部署在联邦学习系统的各参与方。 16 | 17 | ### 样本对齐 18 | 19 | 隐私集合求交(Private Set Intersection,PSI)技术是纵向联邦学习中数据样本对齐的常用解决方案。业界PSI实现方案有多种:基于电路、基于公钥加密、基于不经意传输协议和基于全同态加密等。不同PSI方案各有优劣势。例如,基于公钥加密方案不需要辅助服务器运行,但公钥加密的计算开销大;而基于不经意传输方案计算性能高,但通信开销较大。因此在具体应用时,要根据实际场景来选择功能、性能和安全之间的最佳平衡方案。 20 | 21 | 基于RSA盲签名是一种基于公钥加密的经典PSI方法,也是当前业界纵向联邦学习系统中广泛应用的技术之一。下面以企业A和企业B为例描述RSA盲签名算法的基本流程。 22 | 23 | ![纵向联邦样本对齐](../img/ch10/ch10-federated-learning-vfl-data.png) 24 | :width:`600px` 25 | :label:`federated-learning-vfl-data` 26 | 27 | 企业A作为服务端,拥有一个包含了标签数据+样本ID的集合。企业B则作为客户端,拥有样本ID集合。首先,企业A利用RSA算法生成私钥和公钥。其中,私钥保留在服务端,公钥则发送给企业B。 28 | 29 | 服务端利用RSA算法计算出参与样本对齐的ID的签名: 30 | $$t_j=H^{'}(K_{a:j})$$ 31 | 其中,$K_{a:j}=(H(a_j))^d \ mod \ n$,是采用私钥$d$加密的对$H(a_j)$的RSA加密的结果。$H()$和$H^{'}()$是哈希函数。 32 | 33 | _同样,在客户端侧对样本ID进行公钥加密,并乘以一个随机数$R_{b,i}$用于加盲扰动: 34 | $$y_i=H(b_i)\cdot(R_{b,i})^e \ mod \ n$$ 35 | 客户端侧将上述计算出来的$\{y_1,...,y_v\}$值传输给服务端侧。服务端侧收到$y_i$值后,使用私钥$d$进行签名并计算: 36 | $$y_i^{'}=y_i^d \ mod \ n$$ 37 | 然后将计算出的$\{y_1^{'},...,y_v^{'}\}$和$\{t_1,...,t_w\}$发送给客户端侧。 38 | 而客户端侧收到$y_i^{'}$和$t_j$后,首先完成去盲操作: 39 | $$K_{b:i}={y_i}^{'}/R_{b,i}$$ 40 | 并将自己的ID签名与服务端发过来的ID签名进行样本对齐,得到加密和哈希组合状态下的ID交集$I$, 41 | $${t_i}^{'}=H^{'}(K_{b:i}) \\I=\{t_1,...,t_w\}\cap \{{t_1}^{'},...,{t_v}^{'}\}$$ 42 | 43 | 最后,将对齐后的样本ID交集$I$发送给服务端,服务端利用自身的映射表单独求取明文结果。这样企业A和企业B在加密状态下完成了求取相交的用户集合,并且在整个过程中双方非重叠样本ID都不会对外暴露。 44 | 45 | ### 联合训练 46 | 47 | 在样本ID对齐后,开发人员就可以使用这些公共的数据来建立机器学习模型。 48 | 49 | 目前,线性回归、决策树和神经网络等模型已经被广泛应用到纵向联邦学习系统中。在纵向联邦学习的模型训练过程中,一般会引入第三方协作者C来实现中心服务器功能,并且假设这个第三方协作者C是可信的,不会与其他参与方合谋。中心服务器在训练过程中作为中立方,产生和分发密钥,并对加密数据进行解密和计算。但中心服务器角色是非必须的,例如在两方联邦学习的场景下,不需要第三方协作者C来协调双方的训练任务,可以由具有标签数据的企业A来充当中心服务器的角色。不失一般性,下面继续以包含第三方协作者C的方案来描述纵向联邦学习模型联合训练过程。 50 | 51 | ![纵向联邦联合建模](../img/ch10/ch10-federated-learning-vfl-train.svg) 52 | :width:`800px` 53 | :label:`federated-learning-vfl-train` 54 | 55 | - 第一步:由第三方协作者C创建密钥对,将公钥发送给企业A和B。 56 | - 第二步:在企业A和B侧分别计算梯度和损失计算需要的中间结果,并进行加密和交换。 57 | - 第三步:企业A和B分别计算加密梯度和添加掩码。同时企业A还将计算加密损失值。计算完成后,企业A和B向第三方协作者C发送加密后的值。 58 | - 第四步:第三方协作者C对梯度和损失值解密,然后将结果发送回企业A和B。 59 | - 第五步:企业A和B将收到的值首先去除梯度上的掩码,然后更新本地模型参数。 60 | 61 | 在整个训练过程中,企业A和B之间的任何敏感数据都是经过加密算法加密之后再发出的各自的信任域。同态加密(Homomorphic Encryption,HE)是业界联邦学习框架常用的算法之一。同态加密是指加密过后的两份数据进行某些运算之后直接解密,可以得到真实数据经过相同运算的结果。当这种运算是加法时,就称为加法同态加密。将加密函数记为$[[\cdot]]$。 62 | -------------------------------------------------------------------------------- /chapter_frontend_and_ir/ai_compiler_design_principle.md: -------------------------------------------------------------------------------- 1 | AI编译器设计原理 2 | ---- 3 | 4 | 无论是传统编译器还是AI编译器,它们的输入均为用户的编程代码,输出也机器执行的高效代码。进阶篇将用两个章节详细介绍AI编译器,里面的很多概念借用了通用编译器中的概念,如AOT(Ahead of Time提前编译)、JIT(Just in time 即时)、IR(Intermediate Representation中间表示)、PASS优化、AST(Abstract Trees)、副作用、闭包等概念,和编译器教材中对应概念的定义相同,对编译器相关概念感兴趣的读者可以翻阅相关的编译原理教材,本书会将讨论重点放在机器学习编译器相较于传统编译器的独特设计与功能上。 5 | 6 | AI编译器的设计受到了主流编译器(如LLVM)的影响。为了方便理解AI编译器,首先通过 :numref:`LLVM_basic_struc`展示LLVM编译器的架构。 7 | 8 | ![LLVM编译器基础架构](../img/ch04/LLVM基础结构.png) 9 | :width:`800px` 10 | :label:`LLVM_basic_struc` 11 | 12 | LLVM包含了前端、IR和后端三个部分。前端将高级语言转换成IR,后端将IR转换成目标硬件上的机器指令,IR作为桥梁在前后端之间进行基于IR的各种优化。这样无论是新增硬件的支持,还是新增前端的支持,都可以尽可能地复用IR相关的部分。IR可以是单层的,也可以是多层的, LLVM IR是典型的单层IR,其前后端优化都基于相同的LLVM IR进行。 13 | 14 | AI编译器一般采用多层级IR设计。 :numref:`TF_multi_ir`展示了TensorFlow利用MLIR实现多层IR设计的例子(被称为TensorFlow-MLIR)。其包含了三个层次的IR,即TensorFlow Graph IR, XLA(Accelerated Linear Algebra,加速线性代数)、HLO(High Level Operations,高级运算)以及特定硬件的LLVM IR 或者TPU IR,下面就不同的层级IR和其上的编译优化做一个简要介绍。 15 | 16 | ![TensorFlow的多层IR设计](../img/ch04/TensorFlow-IR.png) 17 | :width:`800px` 18 | :label:`TF_multi_ir` 19 | 20 | 计算图中涉及的编译优化一般称为图编译优化。Graph IR主要实现整图级别的优化和操作,如图优化、图切分等,比较适合静态图的执行模式。由于整图级别的IR缺少相应的硬件信息,难以进行硬件相关的优化,所以在中间层次就出现了硬件相关的通用编译优化,比如XLA、Tensor RT、MindSpore的图算融合等,它们能够针对不同的硬件进行算子融合等优化,提升不同网络在特定硬件上的执行性能。 21 | 本书“编译器后端”章节的硬件通用优化中有一个小节专门介绍图算融合编译器的相关设计。 22 | 最后一个层次的IR是特定硬件加速器专有的IR,一般由硬件厂商自带的编译器提供,如Ascend硬件自带的TBE编译器就是基于TVM的Halide IR生成高效的执行算子。 23 | 24 | 多层级IR的优势是IR表达上更加地灵活,可以在不同层级的IR上进行合适的PASS优化,更加便捷和高效。 25 | 但是多层级IR也存在一些劣势。首先,多层级IR需要进行不同IR之间的转换,而IR转换要做到完全兼容是非常困难的,工程工作量很大,还可能带来信息的损失。上一层IR优化掉某些信息之后,下一层需要考虑其影响,因此IR转换对优化执行的顺序有着更强的约束。其次,多层级IR有些优化既可以在上一层IR进行,也可以在下一层IR进行,让框架开发者很难选择。最后,不同层级IR定义的算子粒度大小不同,可能会给精度带来一定的影响。为了解决这一问题,机器学习框架如MindSpore采用统一的IR设计(MindIR)。 :numref:`MS_Compiler`展示了MindSpore的AI编译器内部的运行流程。其中,编译器前端主要指图编译和硬件无关的优化,编译器后端主要指硬件相关优化、算子选择等。 26 | 27 | ![MindSpore编译器处理流程](../img/ch04/编译器整体流程.png) 28 | :width:`800px` 29 | :label:`MS_Compiler` -------------------------------------------------------------------------------- /chapter_frontend_and_ir/common_frontend_optimization_pass.md: -------------------------------------------------------------------------------- 1 | 常见前端编译优化方法 2 | -------------------- 3 | 4 | 和传统编译器相同,机器学习编译器也会进行编译优化。编译优化意在解决编译生成的中间表示的低效性,使得代码的长度变短,编译与运行的时间减少,执行期间处理器的能耗变低。编译优化可以分为与硬件无关的优化和与硬件相关的编译优化。因为前端是不感知具体后端硬件的,因此前端执行的全部都是与硬件无关的编译优化。 5 | 6 | ### 前端编译优化简介 7 | 8 | 大多数编译优化器会由一系列的"趟"(Pass)来组成。每个"趟"以中间表示为输入,又以新生成的中间表示为输出。一个"趟"还可以由几个小的"趟"所组成。一个"趟"可以运行一次,也可以运行多次。 9 | 10 | 在编译优化中,优化操作的选择以及顺序对于编译的整体具有非常关键的作用。优化操作的选择决定了优化器能够感知中间表示中的哪些低效性,也决定了编译器将要如何去重写中间表示以消除这种低效性。优化操作的顺序决定了各趟操作的执行顺序。编译器可以根据具体需要运行不同的编译优化操作。也可以根据编译优化级别来调整优化的次数,种类以及顺序。 11 | 12 | ![编译优化的"趟"结构](../img/ch04/编译优化-pass结构.svg) 13 | :width:`800px` 14 | :label:`pass_structure` 15 | 16 | ### 常见编译优化方法介绍及实现 17 | 18 | 前端编译优化的方法有很多,机器学习框架也有很多不同于传统编译器的优化方式。在本小节当中,我们会介绍三种常见且通用的前端编译优化方法。 19 | 20 | 1\. 无用与不可达代码消除 21 | 22 | 如 :numref:`pass_useless_code_elimination`所示。无用代码是指输出结果没有被任何其他代码所使用的代码。不可达代码是指没有有效的控制流路径包含该代码。删除无用或不可达的代码可以使得中间表示更小,提高程序的编译与执行速度。无用与不可达代码一方面有可能来自于程序编写者的编写失误,也有可能是其他编译优化所产生的结果。 23 | 24 | ![无用代码消除](../img/ch04/编译优化-无用代码消除.svg) 25 | :width:`600px` 26 | :label:`pass_useless_code_elimination` 27 | 28 | 2\. 常量传播、常量折叠 29 | 30 | 常量传播:如 :numref:`pass_constant_broadcast`所示,如果某些量为已知值的常量,那么可以在编译时刻将使用这些量的地方进行替换。 31 | 32 | 常量折叠:如 :numref:`pass_constant_broadcast`所示,多个量进行计算时,如果能够在编译时刻直接计算出其结果,那么变量将由常量替换。 33 | 34 | ![常量传播与常量折叠](../img/ch04/编译优化-常量传播与常量折叠.svg) 35 | :width:`600px` 36 | :label:`pass_constant_broadcast` 37 | 38 | 3\. 公共子表达式消除 39 | 40 | 如 :numref:`pass_CSE`所示,如果一个表达式E已经计算过了,并且从先前的计算到现在E中所有变量的值都没有发生变化,那么E就成为了公共子表达式。对于这种表达式,没有必要花时间再对它进行计算,只需要直接用前面计算过的表达式结果代替E就可以了。 41 | 42 | ![公共子表达式消除](../img/ch04/编译优化-公共子表达式消除.svg) 43 | :width:`600px` 44 | :label:`pass_CSE` 45 | -------------------------------------------------------------------------------- /chapter_frontend_and_ir/index.md: -------------------------------------------------------------------------------- 1 | # AI编译器和前端技术 2 | 编译器作为计算机系统的核心组件,在机器学习框架设计中也扮演着重要的角色,并衍生出了一个专门的编译器种类:AI编译器。AI编译器既要对上承接模型算法的变化,满足算法开发者不断探索的研究诉求,又要对下在最终的二进制输出上满足多样性硬件的诉求,满足不同部署环境的资源要求。既要满足框架的通用普适性,又要满足易用性的灵活性要求,还要满足性能的不断优化诉求。AI编译器保证了机器学习算法的便捷表达和高效执行,日渐成为了机器学习框架设计的重要一环。 3 | 4 | 本章将先从AI编译器的整体框架入手, 介绍AI编译器的基础结构。接下来,本章会详细讨论编译器前端的设计,并将重点放在中间表示以及自动微分两个部分。有关AI编译器后端的详细知识, 将会在后续的第五章进行讨论。 5 | 6 | 本章的学习目标包括: 7 | 8 | - 理解AI编译器的基本设计原理 9 | 10 | - 理解中间表示的基础概念,特点和实现方法 11 | 12 | - 理解自动微分的基础概念,特点和实现方法 13 | 14 | - 了解类型系统和静态推导的基本原理 15 | 16 | - 了解编译器优化的主要手段和常见优化方法 17 | 18 | 19 | ```toc 20 | :maxdepth: 2 21 | 22 | ai_compiler_design_principle 23 | overview_of_frontend 24 | intermediate_representation 25 | ad 26 | type_system_and_static_analysis 27 | common_frontend_optimization_pass 28 | summary 29 | ``` 30 | -------------------------------------------------------------------------------- /chapter_frontend_and_ir/overview_of_frontend.md: -------------------------------------------------------------------------------- 1 | AI编译器前端技术概述 2 | ---- 3 | 4 | :numref:`compiler_frontend_struc`展示了机器学习编译器前端的基础结构。其中,对源程序的解析过程与传统编译器是大致相同的,本章节不对这部分进行更细致的讨论。机器学习框架的编译器前端的独特之处主要在于对自动微分功能的支持。为了满足自动微分功能带来的新需求,机器学习框架需要在传统中间表示的基础上设计新的中间表示结构。因此,本章节的介绍重点会放在中间表示和自动微分这两个部分,随后会简要探讨类型系统、静态分析和前端优化等编译器的基础概念。 5 | 6 | ![译器前端基础结构](../img/ch04/编译器前端基础架构.svg) 7 | :width:`800px` 8 | :label:`compiler_frontend_struc` 9 | 10 | ### 中间表示 11 | 12 | 中间表示是编译器用于表示源代码的数据结构或代码,是程序编译过程中介于源语言和目标语言之间的程序表示。传统机器学习框架的中间表示分为三大类,分别是线性中间表示,图中间表示以及混合中间表示。然而,传统编译器的中间表示难以完全满足机器学习框架对于中间表示的一系列需求。因此,机器学习框架的开发者在传统中间表示的设计基础上不断扩展,提出了很多适用于机器学习框架的中间表示。 13 | 14 | ### 自动微分 15 | 16 | 自动微分(Automatic Differentiation, 17 | AD)是一种介于符号微分和数值微分之间的针对计算图进行符号解析的求导方法,用于计算函数梯度值。深度学习等现代AI算法通过使用大量数据来学习拟合出一个优化后带参模型,其中使用的学习算法多是基于现实数据在模型中的经验误差,通过梯度下降的方法来更新模型的参数。因此,自动微分在深度学习中处于非常重要的地位,是整个训练算法的核心组件之一。自动微分通常在编译器前端优化中实现,通过对中间表示的符号解析来生成带有梯度函数的中间表示。 18 | 19 | ### 类型系统与静态分析 20 | 21 | 为了有效减少程序在运行时可能出现的错误,编译器的前端引入了类型系统(Type 22 | System)和静态分析(Static 23 | Analysis)系统。类型系统可以防止程序在运行时发生类型错误,而静态分析能够为编译优化提供线索和信息,有效减少代码中存在的结构性错误、安全漏洞等问题。 24 | 25 | ### 前端编译优化 26 | 27 | 编译优化意在解决代码的低效性,无论是在传统编译器还是在机器学习框架中都起着很重要的作用。前端的编译优化与硬件无关。 28 | -------------------------------------------------------------------------------- /chapter_frontend_and_ir/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 中间表示是编译器的核心数据结构之一,是程序编译过程中介于源语言和目标语言之间的程序表示。 4 | 5 | - 传统编译器的中间表示从组织结构出发,可以分为线性中间表示,图中间表示以及混合中间表示。 6 | 7 | - 机器学习框架对中间表示有一系列新的需求,这些新的需求是传统中间表示所不能完美支持的。因此需要在传统中间表示的基础上扩展新的,更适用于机器学习框架的中间表示。 8 | 9 | - 自动微分的基本思想是将计算机程序中的运算操作分解为一个有限的基本操作集合,且集合中基本操作的求导规则均为已知,在完成每一个基本操作的求导后,使用链式法则将结果组合得到整体程序的求导结果。 10 | 11 | - 自动微分根据链式法则的组合顺序,可以分为前向自动微分与反向自动微分。 12 | 13 | - 前向自动微分更适用于对输入维度小于输出维度的网络求导,反向自动微分则更适用于对输出维度小于输入维度的网络求导。 14 | 15 | - 自动微分的实现方法大体上可以划分为基本表达式法、操作符重载法以及代码变化法。 16 | 17 | - 类型系统是指类型的集合以及使用类型来规定程序行为的规则,用于定义不同的类型,指定类型的操作和类型之间的相互作用,广泛应用于编译器、解释器和静态检查工具中。 18 | 19 | - 静态分析,是指在不实际运行程序的情况下,通过词法分析、语法分析、控制流、数据流分析等技术对代码进行分析验证的技术 20 | 21 | - 编译优化意在解决编译生成的中间表示的低效性,前端执行的均为与硬件无关的编译优化。 22 | 23 | 24 | ## 扩展阅读 25 | 26 | - 一种基于图的中间表示类型: [综述](https://dl.acm.org/doi/10.1145/202530.202534) 27 | 28 | - 机器学习框架中的自动微分: [综述](https://arxiv.org/abs/1502.05767) 29 | 30 | - 函数式框架中的反向自动微分: [综述](https://dl.acm.org/doi/10.1145/1330017.1330018) 31 | -------------------------------------------------------------------------------- /chapter_frontend_and_ir/type_system_and_static_analysis.md: -------------------------------------------------------------------------------- 1 | 类型系统和静态分析 2 | ------------------ 3 | 4 | 上一章节介绍了自动微分的基本概念和实现方法,自动微分是机器学习框架中不可或缺的核心功能。在编译器前端的设计中,为了提高编译器的抽象能力和程序运行的正确性,有效减少程序在运行时可能出现的错误,编译器引入了类型系统和静态分析系统,接下来将对它们的基本概念、主要功能、常见系统进行介绍。 5 | 6 | ### 类型系统概述 7 | 8 | 程序设计语言中,类型是指数值、表达式、函数等属性内容。类型系统是指类型的集合以及使用类型来规定程序行为的规则。类型系统用于定义不同的类型,指定类型的操作和类型之间的相互作用,广泛应用于编译器、解释器和静态检查工具中。类型系统提供的主要功能有: 9 | 10 | 1)正确性。编译器的类型系统引入了类型检查技术,用于检测和避免运行时错误,确保程序运行时的安全性。通过类型推导与检查,编译器能够捕获大多数类型相关的异常报错,避免执行病态程序导致运行时错误,保证内存安全,避免类型间的无效计算和语义上的逻辑错误。 11 | 12 | 2)优化。静态类型检查可以提供有用的信息给编译器,从而使得编译器可以应用更有效的指令,节省运行时的时间。 13 | 14 | 3)抽象。在安全的前提下,一个强大的类型系统的标准是抽象能力。通过合理设计抽象,开发者可以更关注更高层次的设计。 15 | 16 | 4)可读性。阅读代码时,明确的类型声明有助于理解程序代码。 17 | 18 | 机器学习框架一般使用Python语言作为描述网络模型结构的前端语言。Python语言是一门动态强类型的语言,入门简单易学习,开发代码简洁高效,但由于其解释执行的方式,运行速度往往较慢。Python前端语言给用户带来了动态灵活的语义和高效的开发效率,但是若想要生成运行高效的后端代码,后端框架需要优化友好的静态强类型中间表示。因此,需要一种高效可靠的静态分析方法作为桥梁,将Python前端表示转换成等价的静态强类型中间表示,以此给用户同时带来高效的开发效率和运行效率,例如Hindley--Milner(HM)类型系统。这是一种具有参数多态性的简单类型lambda演算的类型系统。它最初由J. 19 | Roger Hindley 提出 :cite:`1969The`,并由Robin Milner 20 | 进行扩展和验证 :cite:`1978A` 。后来,路易斯·达马斯(Luis 21 | Damas)对HM类型推导方法进行了详尽的分析和证明 :cite:`1982Principal`,并将其扩展到支持具有多态引用的系统。Hindley--Milner类型系统的目标是在没有给定类型注解的情况下,自动推导出任意表达式的类型。其算法具有抽象性和通用性,采用简洁的符号表示,能够根据表达式形式推导出明确直观的定义,常用于类型推导和类型检查。因此,Hindley--Milner类型系统广泛应用于编程语言设计中,比如Haskell和Ocaml。 22 | 23 | ### 静态分析概述 24 | 25 | 在设计好类型系统后,编译器需要使用静态分析系统来对中间表示进行静态检查与分析。语法解析模块(parser)将程序代码解析为抽象语法树(AST)并生成中间表示。此时的中间表示缺少类型系统中定义的抽象信息,因此引入静态分析模块,对中间表示进行处理分析,并且生成一个静态强类型的中间表示,用于后续的编译优化、自动并行以及自动微分等。在编译器前端的编译过程中,静态分析可能会被执行多次,有些框架还会通过静态分析的结果判断是否终止编译优化。 26 | 27 | 静态分析模块基于抽象释义对中间表示进行类型推导、常量传播、泛型特化等操作,这些专业术语的含义分别为: 28 | 29 | 抽象释义:通过抽象解释器将语言的实际语义近似为抽象语义,只获取后续优化需要的属性,进行不确定性的解释执行。抽象值一般包括变量的类型和维度。 30 | 31 | 类型推导:在抽象释义的基础上,编译器推断出程序中变量或表达式的抽象类型,方便后续利用类型信息进行编译优化。 32 | 33 | 泛型特化:泛型特化的前提是编译器在编译期间可以进行类型推导,提供类型的上下文。在编译期间,编译器通过类型推导确定调用函数时的类型,然后,编译器会通过泛型特化,进行类型取代,为每个类型生成一个对应的函数方法。 34 | 35 | 接下来以MindSpore框架为例,简要介绍一下静态分析模块的具体实现。MindSpore采用抽象释义的方法,对抽象值做不确定的抽象语义的解释执行,函数图中每个节点的抽象值是所期望得到的程序静态信息。基本的抽象释义方法流程可以理解为,从MindIR的顶层函数图入口开始解释执行,将函数图中所有节点进行拓扑排序,根据节点的语义递归推导各节点的抽象值。当遇到函数子图时,递归进入函数子图进行解释执行,最后返回顶层函数输出节点的抽象值。根据抽象释义方法流程,MindSpore的静态分析模块主要分为抽象域模块、缓存模块、语义推导模块和控制流处理模块。 36 | 37 | ![静态分析模块](../img/ch04/静态分析-静态分析模块.png) 38 | :width:`850px` 39 | :label:`static_analysis_module` 40 | -------------------------------------------------------------------------------- /chapter_introduction/applications.md: -------------------------------------------------------------------------------- 1 | ## 机器学习应用 2 | 3 | 通俗来讲,机器学习是指从数据中学习出有用知识的技术。以学习模式分类,机器学习可以分为监督学习(Supervised Learning)、无监督学习(Unsupervised Learning)和强化学习(Reinforcement Learning)等。 4 | 5 | * 监督学习是已知输入和输出的对应关系下的机器学习场景。比如给定输入图像和它对应的离散标签。 6 | * 无监督学习是只有输入数据但不知道输出标签下的机器学习场景。比如给定一堆猫和狗的图像,自主学会猫和狗的分类,这种无监督分类也称为聚类(Clustering)。 7 | * 强化学习则是给定一个学习环境和任务目标,算法自主地去不断改进自己以实现任务目标。比如 AlphaGo围棋就是用强化学习实现的,给定的环境是围棋的规则,而目标则是胜利得分。 8 | 9 | 从应用领域上划分,机器学习应用包括计算机视觉、自然语言处理和智能决策等。 10 | 狭义上来讲,基于图像的应用都可归为计算机视觉方面的应用,典型的应用有人脸识别、物体识别、目标跟踪、人体姿态估计、图像理解等。 11 | 计算机视觉方法广泛应用于自动驾驶、智慧城市、智慧安防等领域。 12 | 13 | 自然语言处理涉及文本或者语音方面的应用,典型的应用包括语言翻译、文本转语音、语音转文本、文本理解、图片风格变换等。 14 | 计算机视觉和自然语言处理有很多交集,如图像的文本描述生成、基于文本的图像生成、基于文本的图像处理等应用都同时涉及语言和图像两种数据类型。 15 | 16 | 智能决策的应用往往通过结合计算机视觉、自然语言处理、强化学习、控制论等技术手段,实现决策类任务。智能决策方法广泛用于机器人、自动驾驶、游戏、推荐系统、智能工厂、智能电网等领域。 17 | 18 | 不同的机器学习应用底层会应用不同的机器学习算法,如支持向量机(Support Vector Machine,SVM)、逻辑回归(Logistic Regression)、朴素贝叶斯(Naive Bayes)算法等。近年来,得益于海量数据的普及,神经网络(Neural Networks)算法的进步和硬件加速器的成熟,深度学习(Deep Learning)开始蓬勃发展。虽然机器学习算法很多,但无论是经典算法还是深度学习算法的计算往往以向量和矩阵运算为主体,因此本书主要通过神经网络为例子展开机器学习系统的介绍。 -------------------------------------------------------------------------------- /chapter_introduction/architecture.md: -------------------------------------------------------------------------------- 1 | ## 机器学习框架的基本组成原理 2 | 3 | 一个完整的机器学习框架一般具有如图 :numref:`framework-architecture` 所示的基本架构。 4 | 5 | ![机器学习框架基本构成](../img/ch01/framework-architecture.png) 6 | :width:`600px` 7 | :label:`framework-architecture` 8 | 9 | - **编程接口:** 10 | 考虑到机器学习开发人员背景的多样性,机器学习框架首先需要提供以高层次编程语言(如Python)为主的编程接口。同时,机器学习框架为了优化运行性能,需要支持以低层次编程语言(如C和C++)为主的系统实现,从而实现操作系统(如线程管理和网络通讯等)和各类型硬件加速器的高效使用。 11 | 12 | - **计算图:** 13 | 利用不同编程接口实现的机器学习程序需要共享一个运行后端。实现这一后端的关键技术是计算图技术。计算图定义了用户的机器学习程序,其包含大量表达计算操作的算子节点(Operator Node),以及表达算子之间计算依赖的边(Edge)。 14 | 15 | - **编译器前端:** 16 | 机器学习框架往往具有AI编译器来构建计算图,并将计算图转换为硬件可以执行的程序。这个编译器首先会利用一系列编译器前端技术实现对程序的分析和优化。编译器前端的关键功能包括实现中间表示、自动微分、类型推导和静态分析等。 17 | 18 | - **编译器后端和运行时:** 19 | 完成计算图的分析和优化后,机器学习框架进一步利用编译器后端和运行时实现针对不同底层硬件的优化。常见的优化技术包括分析硬件的L2/L3缓存大小和指令流水线长度,优化算子的选择或者调度顺序。 20 | 21 | - **异构处理器:** 22 | 机器学习应用的执行由中央处理器(Central Processing Unit,CPU)和硬件加速器(如英伟达GPU、华为Ascend和谷歌TPU)共同完成。其中,非矩阵操作(如复杂的数据预处理和计算图的调度执行)由中央处理器完成。矩阵操作和部分频繁使用的机器学习算子(如Transformer算子和Convolution算子)由硬件加速器完成。 23 | 24 | - **数据处理:** 25 | 机器学习应用需要对原始数据进行复杂预处理,同时也需要管理大量的训练数据集、验证数据集和测试数据集。这一系列以数据为核心的操作由数据处理模块(例如TensorFlow的tf.data和PyTorch的DataLoader)完成。 26 | 27 | - **模型部署:** 28 | 在完成模型训练后,机器学习框架下一个需要支持的关键功能是模型部署。为了确保模型可以在内存有限的硬件上执行,会使用模型转换、量化、蒸馏等模型压缩技术。同时,也需要实现针对推理硬件平台(例如英伟达Orin)的模型算子优化。最后,为了保证模型的安全(如拒绝未经授权的用户读取),还会对模型进行混淆设计。 29 | 30 | - **分布式训练:** 31 | 机器学习模型的训练往往需要分布式的计算节点并行完成。其中,常见的并行训练方法包括数据并行、模型并行、混合并行和流水线并行。这些并行训练方法通常由远端程序调用(Remote Procedure Call, RPC)、集合通信(Collective Communication)或者参数服务器(Parameter Server)实现。 -------------------------------------------------------------------------------- /chapter_introduction/design.md: -------------------------------------------------------------------------------- 1 | ## 机器学习框架的设计目标 2 | 3 | 为了支持在不同应用中高效开发机器学习算法,人们设计和实现了**机器学习框架**(如TensorFlow、PyTorch、MindSpore等)。广义来说,这些框架实现了以下共性的设计目标: 4 | 5 | - **神经网络编程:** 6 | 深度学习的巨大成功使得神经网络成为了许多机器学习应用的核心。根据应用的需求,人们需要定制不同的神经网络,如卷积神经网络(Convolutional Neural Networks)和自注意力神经网络(Self-Attention Neural Networks)等。这些神经网络需要一个共同的系统软件进行开发、训练和部署。 7 | 8 | - **自动微分:** 9 | 训练神经网络会具有模型参数。这些参数需要通过持续计算梯度(Gradients)迭代改进。梯度的计算往往需要结合训练数据、数据标注和损失函数(Loss 10 | Function)。考虑到大多数开发人员并不具备手工计算梯度的知识,机器学习框架需要根据开发人员给出的神经网络程序,全自动地计算梯度。这一过程被称之为自动微分。 11 | 12 | - **数据管理和处理:** 13 | 机器学习的核心是数据。这些数据包括训练、验证、测试数据集和模型参数。因此,需要系统本身支持数据读取、存储和预处理(例如数据增强和数据清洗)。 14 | 15 | - **模型训练和部署:** 16 | 为了让机器学习模型达到最佳的性能,需要使用优化方法(例如Mini-Batch SGD)来通过多步迭代反复计算梯度,这一过程称之为训练。训练完成后,需要将训练好的模型部署到推理设备。 17 | 18 | - **硬件加速器:** 19 | 神经网络的相关计算往往通过矩阵计算实现。这一类计算可以被硬件加速器(例如,通用图形处理器-GPU)加速。因此,机器学习系统需要高效利用多种硬件加速器。 20 | 21 | - **分布式执行:** 22 | 随着训练数据量和神经网络参数量的上升,机器学习系统的内存用量远远超过了单个机器可以提供的内存。因此,机器学习框架需要天然具备分布式执行的能力。 23 | 24 | 在设计机器学习框架之初,开发者曾尝试通过传统的**神经网络开发库**(如Theano和Caffe)、以及**数据处理框架**(如Apache Spark和Google Pregel)等方式达到以上设计目标。可是他们发现, 25 | 神经网络库虽然提供了神经网络开发、自动微分和硬件加速器的支持,但缺乏管理和处理大型数据集、模型部署和分布式执行的能力,无法满足当今产品级机器学习应用的开发任务。 26 | 另一方面,虽然并行数据计算框架具有成熟的分布式运行和数据管理能力,但缺乏对神经网络、自动微分和加速器的支持,并不适合开发以神经网络为核心的机器学习应用。 27 | 28 | 考虑到上述已有软件系统的种种不足,许多公司开发人员和大学研究人员开始从头设计和实现针对机器学习的软件框架。在短短数年间,机器学习框架如雨后春笋般出现(较为知名的例子包括TensorFlow、PyTorch、MindSpore、MXNet、PaddlePaddle、OneFlow、CNTK等),极大推进了人工智能在上下游产业中的发展。表 :numref:`comparison_of_ml_frameworks` 总结了机器学习框架和相关系统的区别。 29 | 30 | :机器学习框架和相关系统的区别 31 | 32 | | 方式 | 神经网络 | 自动微分 | 数据管理 | 训练和部署 | 硬件加速器 | 分布式执行 | 33 | |:-: |:-:| :-: |:-:|:-: |:-:|:-:| 34 | | 神经网络库 | 是 | 是 | 否 | 否 | 是 | 否 | 35 | | 大数据框架 | 否 | 否 | 是 | 否 | 否 | 是 | 36 | | 机器学习框架 | 是 | 是 | 是 | 是 | 是 | 是 | 37 | :label:`comparison_of_ml_frameworks` 38 | -------------------------------------------------------------------------------- /chapter_introduction/ecosystem.md: -------------------------------------------------------------------------------- 1 | ## 机器学习系统生态 2 | 3 | 以机器学习框架为核心,人工智能社区创造出了庞大的**机器学习系统**生态。广义来说,机器学习系统是指实现和支持机器学习应用的各类型软硬件系统的泛称。图 :numref:`system-ecosystem` 总结了各类型的机器学习系统。 4 | 5 | ![机器学习系统和相关生态](../img/ch01/system-ecosystem.png) 6 | :width:`600px` 7 | :label:`system-ecosystem` 8 | 9 | - **联邦学习:** 10 | 随着用户隐私保护和数据保护法的出现,许多机器学习应用无法直接接触用户数据完成模型训练。因此这一类应用需要通过机器学习框架实现联邦学习(Federated Learning)。 11 | 12 | - **推荐系统:** 13 | 将机器学习(特别是深度学习)引入推荐系统在过去数年取得了巨大的成功。相比于传统基于规则的推荐系统,深度学习推荐系统能够有效分析用户的海量特征数据,从而实现在推荐准确度和推荐时效性上的巨大提升。 14 | 15 | - **强化学习:** 16 | 强化学习具有数据收集和模型训练方法的特殊性。因此,需要基于机器学习框架进一步开发专用的强化学习系统。 17 | 18 | - **可解释AI:** 19 | 随着机器学习在金融、医疗和政府治理等关键领域的推广,基于机器学习框架进一步开发的可解释性AI系统正得到日益增长的重视。 20 | 21 | - **机器人:** 22 | 机器人是另一个开始广泛使用机器学习框架的领域。相比于传统的机器人视觉方法,机器学习方法在特征自动提取、目标识别、路径规划等多个机器人任务中获得了巨大成功。 23 | 24 | - **图学习:** 25 | 图(Graph)是最广泛使用的数据结构之一。许多互联网数据(如社交网络、产品关系图)都由图来表达。机器学习算法已经被证明是行之有效的分析大型图数据的方法。这种针对图数据的机器学习系统被称之为图学习系统(Graph Learning System)。 26 | 27 | - **科学计算:** 28 | 科学计算覆盖许多传统领域(如电磁仿真、图形学、天气预报等),这些领域中的许多大规模问题都可以有效利用机器学习方法求解。因此,针对科学计算开发机器学习系统变得日益普遍。 29 | 30 | - **机器学习集群调度:** 31 | 机器学习集群一般由异构处理器、异构网络甚至异构存储设备构成。同时,机器学习集群中的计算任务往往具有共同的执行特点(如基于集合通信算子AllReduce迭代进行)。因此,针对异构设备和任务特点,机器学习集群往往具有特定的调度方法设计。 32 | 33 | - **量子计算:** 34 | 量子计算机一般通过混合架构实现。其中,量子计算由量子计算机完成,而量子仿真由传统计算机完成。由于量子仿真往往涉及到大量矩阵计算,许多量子仿真系统(如TensorFlow Quantum和MindQuantum)都基于机器学习框架实现。 35 | 36 | 本书受限于篇幅,将不会对所有机器学习系统进行深入讲解。目前,本书会从系统设计者的角度出发,对应用在联邦学习、推荐系统、强化学习、可解释AI和机器人中的相关核心系统进行讲解。 37 | -------------------------------------------------------------------------------- /chapter_introduction/index.md: -------------------------------------------------------------------------------- 1 | # 导论 2 | 3 | 本章将会介绍机器学习应用,梳理出机器学习系统的设计目标,总结出机器学习系统的基本组成原理,让读者对机器学习系统有自顶而下的全面了解。 4 | 5 | ```toc 6 | :maxdepth: 2 7 | 8 | applications 9 | design 10 | architecture 11 | ecosystem 12 | readers 13 | ``` -------------------------------------------------------------------------------- /chapter_introduction/readers.md: -------------------------------------------------------------------------------- 1 | ## 图书结构和读者 2 | 3 | 本书由浅入深地讨论机器学习系统的设计原理和实现经验。其中,**基础篇**覆盖编程接口设计和计算图等框架使用者需要了解的核心概念。**进阶篇**覆盖编译器前端、编译器后端、数据管理等框架设计者需要了解的核心概念。最后,**拓展篇**覆盖重要的机器学习系统类别(如联邦学习和推荐系统等),从而为各领域的机器学习爱好者提供统一的框架使用和设计入门教学。 4 | 5 | 本书的常见读者包括: 6 | 7 | - **学生:** 8 | 本书将帮助学生获得大量机器学习系统的设计原则和一手实践经验,从而帮助其更全面理解机器学习算法的实践挑战和理论优劣。 9 | 10 | - **科研人员:** 11 | 本书将帮助科研人员解决机器学习落地实践中面临的种种挑战,引导设计出能解决大规模实际问题的下一代机器学习算法。 12 | 13 | - **开发人员:** 14 | 本书将帮助开发人员深刻理解机器学习系统的内部架构,从而帮助其开发应用新功能、调试系统性能,并且根据业务需求对机器学习系统进行定制。 -------------------------------------------------------------------------------- /chapter_model_deployment/index.md: -------------------------------------------------------------------------------- 1 | # 模型部署 2 | 3 | 前面的章节讲述了机器学习模型训练系统的基本组成,这一章节将重点讲述模型部署的相关知识。模型部署是将训练好的模型部署到运行环境中进行推理的过程,模型部署的过程中需要解决训练模型到推理模型的转换,硬件资源对模型的限制,模型推理的时延、功耗、内存占用等指标对整个系统的影响以及模型的安全等一系列的问题。 4 | 5 | 本章将主要介绍机器学习模型部署的主要流程,包括训练模型到推理模型的转换、适应硬件限制的模型压缩技术、模型推理及性能优化以及模型的安全保护。 6 | 7 | 本章的学习目标包括: 8 | 9 | - 了解训练模型到推理模型转换及优化 10 | 11 | - 掌握模型压缩的常用方法:量化、稀疏和知识蒸馏 12 | 13 | - 掌握模型推理的流程及常用的性能优化的技术 14 | 15 | - 了解模型安全保护的常用方法 16 | 17 | 18 | ```toc 19 | :maxdepth: 2 20 | 21 | model_deployment_introduction 22 | model_converter_and_optimizer 23 | model_compression 24 | model_inference 25 | model_security 26 | summary 27 | ``` -------------------------------------------------------------------------------- /chapter_model_deployment/model_deployment_introduction.md: -------------------------------------------------------------------------------- 1 | ## 概述 2 | 3 | 模型完成训练后,需要将模型及参数持久化成文件,不同的训练框架导出的模型文件中存储的数据结构不同,这给模型的推理系统带来了不便。推理系统为了支持不同的训练框架的模型,需要将模型文件中的数据转换成统一的数据结构。此外,在训练模型转换成推理模型的过程中,需要进行一些如算子融合、常量折叠等模型的优化以提升推理的性能。 4 | 5 | 推理模型部署到不同的场景,需要满足不同的硬件设备的限制,例如,在具有强大算力的计算中心或数据中心的服务器上可以部署大规模的模型,而在边缘侧服务器、个人电脑以及智能手机上算力和内存则相对有限,部署的模型的规模就相应地要降低。在超低功耗的微控制器上,则只能部署非常简单的机器学习模型。此外,不同硬件对于不同数据类型(如float32、float16、bfloat16、int8等)的支持程度也不相同。为了满足这些硬件的限制,在有些场景下需要对训练好的模型进行压缩,降低模型的复杂度或者数据的精度,减少模型的参数,以适应硬件的限制。 6 | 7 | 模型部署到运行环境中执行推理,推理的时延、内存占用、功耗等是影响用户使用的关键因素,优化模型推理的方式有两种,一是设计专有的机器学习的芯片,相对于通用的计算芯片,这些专有芯片一般在能效比上具有很大的优势。二是通过软硬协同最大程度地发挥硬件的能力。对于第二种方式,以CPU为例,如何切分数据块以满足cache大小,如何对数据进行重排以便计算时可以连续访问,如何减少计算时的数据依赖以提升硬件流水线的并行,如何使用扩展指令集以提升计算性能,这些都需要针对不同的CPU架构进行设计和优化。 8 | 9 | 对于一个企业来讲,模型是属于重要的资产,因此,在模型部署到运行环境以后,保护模型的安全至关重要。本章节会介绍如模型混淆等一些常见的机器学习模型的安全保护手段。 10 | 11 | 针对上述模型部署时的挑战,业界有一些常见的方法: 12 | 13 | - **算子融合** 14 | 15 | 通过表达式简化、属性融合等方式将多个算子合并为一个算子的技术,融合可以降低模型的计算复杂度及模型的体积。 16 | 17 | - **常量折叠** 18 | 19 | 将符合条件的算子在离线阶段提前完成前向计算,从而降低模型的计算复杂度和模型的体积。常量折叠的条件是算子的所有输入在离线阶段均为常量。 20 | 21 | - **模型压缩** 22 | 23 | 通过量化、剪枝等手段减小模型体积以及计算复杂度的技术,可以分为需要重训的压缩技术和不需要重训的压缩技术两类。 24 | 25 | - **数据排布** 26 | 27 | 根据后端算子库支持程度和硬件限制,搜索网络中每层的最优数据排布格式,并进行数据重排或者插入数据重排算子,从而降低部署时的推理时延 28 | 29 | - **模型混淆** 30 | 31 | 对训练好的模型进行混淆操作,主要包括新增网络节点和分支、替换算子名的操作,攻击者即使窃取到混淆后的模型也不能理解原模型的结构。此外,混淆后的模型可以直接在部署环境中以混淆态执行,保证了模型在运行过程中的安全性。 32 | -------------------------------------------------------------------------------- /chapter_model_deployment/model_security.md: -------------------------------------------------------------------------------- 1 | ## 模型的安全保护 2 | AI服务提供商在本地完成模型训练和调优后,将模型部署到第三方外包平台上(如终端设备、边缘设备和云服务器)来提供推理服务。由于AI模型的设计和训练需要投入大量时间、数据和算力,如何保护模型的知识产权(包括模型结构和参数等信息),防止模型在部署过程中的传输、存储以及运行环节被窃取,已经成为服务/模型提供商最为关心的问题之一。 3 | 4 | ### 概述 5 | 模型的安全保护可以分为静态保护和动态保护两个方面。静态保护指的是模型在传输和存储时的保护,目前业界普遍采用的是基于文件加密的模型保护方案,AI模型文件以密文形态传输和存储,执行推理前在内存中解密。在整个推理过程中,模型在内存中始终是明文的,存在被敌手从内存中转储的风险。动态保护指的是模型在运行时的保护,目前业界已有的模型运行时保护方案主要有以下三个技术路线:一是基于TEE(Trusted Execution Environment)的模型保护方案,TEE通常指的是通过可信硬件隔离出来的一个“安全区”,AI模型文件在非安全区加密存储和传输,在安全区中解密运行。该方案在CPU上的推理时延较小,但依赖特定可信硬件,有一定的部署难度。此外,受硬件资源约束,难以保护大规模深度模型,且目前仍无法有效支持异构硬件加速。二是基于密态计算的保护方案,该方案基于密码学方法(如同态加密、多方安全计算等),保证模型在传输、存储和运行过程中始终保持密文状态。该方案不依赖特定硬件,但面临非常大的计算或通信开销问题,且无法保护模型结构信息。三是基于混淆的模型保护方案,该方案主要通过对模型的计算逻辑进行加扰,使得敌手即使能获取到模型也无法理解。与前两种技术路线相比,该方案仅带来较小的性能开销,且精度损失很低,同时,不依赖特定硬件,可支持大模型的保护。下面将重点介绍基于混淆的模型保护技术。 6 | 7 | ### 模型混淆 8 | 模型混淆技术可以自动混淆明文AI模型的计算逻辑,使得攻击者即使在传输和存储时获取到模型也无法理解;且支持模型混淆态执行,保证模型运行时的机密性。同时不影响模型原本的推理结果、仅带来较小的推理性能开销。模型混淆技术主要包含以下几个步骤: 9 | 10 | ![模型混淆实现步骤图](../img/ch08/model_obfuscate.png) 11 | :width:`400px` 12 | :label:`ch08-fig-model_obfuscate` 13 | 14 | 结合 :numref:`ch08-fig-model_obfuscate`,详细阐述模型混淆的执行步骤: 15 | 16 | (1) 解析模型并获取计算图 17 | 18 | 对于一个训练好的模型,首先根据模型结构解析模型文件并获取模型计算逻辑的图表达(计算图)用于后续操作。获取的计算图包括节点标识、节点算子类型、节点参数权重以及网络结构等信息。 19 | 20 | (2) 对计算图的网络结构加扰 21 | 22 | 通过图压缩和图增广等技术,对计算图中节点与节点之间的依赖关系进行加扰,达到隐藏模型真实计算逻辑的效果。其中,图压缩通过整图检查来匹配原网络中的关键子图结构,这些子图会压缩并替换为单个新的计算节点。对于压缩后的计算图,图增广通过在网络结构中加入新的输入/输出边,进一步隐藏节点间的真实依赖关系。新增的输入/输出边可以来自/指向图中现已有的节点,也可以来自/指向本步骤新增的混淆节点。 23 | 24 | > 加扰是指在计算图中添加扰动,来达到模型混淆的目的,常用的加扰手段有添加冗余的节点和边、融合部分子图等等。 25 | 26 | (3) 对计算图的节点匿名化 27 | 28 | 遍历步骤(2)处理后的计算图,筛选出需要保护的节点。对于图中的每个需要保护的节点,将节点标识、节点算子类型以及其他能够描述节点计算逻辑的属性替换为无语义信息的符号。对于节点标识匿名化,本步骤保证匿名化后的节点标识仍然是唯一的,以区分不同的节点。对于算子类型匿名化,为了避免大规模计算图匿名化导致的算子类型爆炸问题,可以将计算图中算子类型相同的节点划分为若干不相交的集合,同一个集合中节点的算子类型替换为相同的匿名符号。步骤(5)将保证节点匿名化后,模型仍然是可被识别和执行的。 29 | 30 | (4) 对计算图的参数权重加扰 31 | 32 | 对于每个需要保护的权重,通过一个随机噪声和映射函数对权重进行加扰。每个权重加扰时可以使用不同的随机噪声和映射函数,步骤(6)将保证权重加扰不会影响模型执行结果的正确性。将经过步骤(2)(3)(4)处理后的计算图保存为模型文件供后续使用。 33 | 34 | (5) 算子接口变换 35 | 36 | 步骤(5)(6)将对每个需要保护的算子类型进行算子形态变换,生成若干候选混淆算子。原算子与混淆算子之间是一对多的对应关系,候选混淆算子的数量等于步骤(3)划分的节点集合的数量。 37 | 本步骤根据步骤(2)(3)(4)的得到的匿名化算子类型、算子输入/输出关系等信息,对相应算子的接口进行变换。算子接口的变换方式包括但不局限于输入输出变换、接口名称变换。其中,输入输出变换通过修改原算子的输入输出数据,使得生成的混淆算子与原算子的接口形态不同。新增的输入输出数据包括步骤(2)图增广新增的节点间数据依赖和步骤(4)权重混淆引入的随机噪声。接口名称变换将原算子名称替换为步骤(3)生成的匿名化算子名称,保证节点匿名化后的模型仍然是可被识别和执行的,且算子的名称不会泄露其计算逻辑。 38 | 39 | (6) 算子实现变换 40 | 41 | 对算子的代码实现进行变换。代码实现的变换方式包括但不局限于字符串加密、冗余代码等软件代码混淆技术,保证混淆算子与原算子实现语义相同的计算逻辑,但是难以阅读和理解。不同的算子可以采用不同代码混淆技术的组合进行代码变换。除代码等价变形之外,混淆算子还实现了一些额外的计算逻辑,如对于步骤(4)中参数被加扰的算子,混淆算子也实现了权重加扰的逆映射函数,用于在算子执行过程中动态消除噪声扰动,保证混淆后模型的计算结果与原模型一致。将生成的混淆算子保存为库文件供后续使用。 42 | 43 | (7) 部署模型和算子库 44 | 45 | 将混淆态模型文件以及相应的混淆算子库文件部署到目标设备上。 46 | 47 | (8) 混淆模型加载 48 | 49 | 根据模型结构解析混淆态模型文件并获取模型计算逻辑的图表达,即经过步骤(2)(3)(4)处理后得到的混淆计算图。 50 | 51 | (9) 计算图初始化 52 | 53 | 对计算图进行初始化,生成执行任务序列。根据安全配置选项,若需要保护模型运行时安全,则直接对混淆计算图进行初始化,生成执行任务序列,序列中的每个计算单元对应一个混淆算子或原算子的执行。若仅需保护模型传输和存储时安全,则可先将内存中的混淆计算图恢复为原计算图,然后对原计算图进行初始化,生成执行任务序列,序列中的每个单元对应一个原算子的执行,这样可以进一步降低推理时的性能开销。 54 | 55 | (10) 推理任务执行 56 | 57 | 根据AI应用程序输入的推理数据,遍历执行任务序列中的每个计算单元,得到推理结果。若当前计算单元对应的算子是混淆算子时,调用混淆算子库;否则,调用原算子库。 58 | -------------------------------------------------------------------------------- /chapter_model_deployment/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 不同的模型部署场景下,通常对于模型大小、运行时内存占用、推理时延和推理功耗等指标有限制。 4 | 5 | - 针对模型大小指标,通常在离线阶段通过模型压缩技术来优化,比如量化技术、剪枝技术、知识蒸馏技术等,除此之外,一部分模型优化技术,比如融合技术等,也有助于模型轻量化,不过其效果比较微弱。 6 | 7 | - 针对运行时内存指标,主要有三方面的优化:优化模型大小、优化部署框架包大小以及优化运行时临时内存。模型大小的优化手段在上一点中已经说明;部署框架包大小主要通过精简框架代码、框架代码模块化等方式来优化。运行时临时内存主要通过内存池实现内存之间的复用来优化。 8 | 9 | - 针对模型的推理时延指标,主要有两方面的优化,一方面是离线时通过模型优化技术和模型压缩技术尽可能降低模型推理所需的计算量;另一方面是通过加大推理的并行力度和优化算子实现来充分挖掘硬件的计算潜力。值得注意的是,除了考虑计算量和算力,推理时的访存开销也是一个重要的影响因素。 10 | 11 | - 针对模型的推理功耗,主要的优化思路是降低模型的计算量,这与针对模型推理时延的优化手段有重合之处,可以参考离线的模型优化技术和模型压缩技术。 12 | 13 | - 本章除了介绍优化模型部署的各方面指标的优化技术以外,还介绍了安全部署相关的技术,如模型混淆、模型加密等。部署安全一方面可以保护企业的重要资产,另一方面可以防止黑客通过篡改模型从而入侵攻击部署环境。 14 | 15 | ## 扩展阅读 16 | 17 | - Google量化白皮书 [量化](https://arxiv.org/abs/1806.08342) 18 | 19 | - 诺亚高精度剪枝算法 [剪枝](https://arxiv.org/abs/2010.10732) 20 | 21 | - 针对多核处理器的自动图并行调度框架 [性能优化](https://proceedings.mlsys.org/paper/2021/file/a5e00132373a7031000fd987a3c9f87b-Paper.pdf) 22 | 23 | - 诺亚量子启发的低比特量化算法 [量化](https://arxiv.org/abs/2009.08695) 24 | 25 | - 诺亚GhostNet极简骨干网络 [网络结构替换](https://arxiv.org/abs/1911.11907) 26 | 27 | - 诺亚加法神经网络 [网络结构替换](https://arxiv.org/abs/1912.13200) 28 | -------------------------------------------------------------------------------- /chapter_preface_advanced/index.md: -------------------------------------------------------------------------------- 1 | # 第二部分:进阶篇 2 | 3 | 下面本书将重点讲解 AI 编译器的基本构成,以及 AI 编译器前端、后端和运行时中的关键技术。本书也将对于硬件加速器、数据处理、模型部署和分布式训练分别进行深入解读,从而为开发者提供从 0 到 1 构建机器学习框架所需的核心知识和实践经验。 4 | -------------------------------------------------------------------------------- /chapter_preface_extension/index.md: -------------------------------------------------------------------------------- 1 | # 第三部分:拓展篇 2 | 3 | 在本书的第三部分,我们将会介绍机器学习框架生态下的众多拓展应用。我们将会首先介绍深度学习推荐系统,这一类系统是深度学习应用最成功的领域之一,在各大互联网公司中得到了大量部署。 4 | 其后,我们将会介绍联邦学习系统,这一类希望在数据隐私保护意识快速崛起的今天具有举足轻重的作用。我们同时也会介绍可解释性AI系统,这一类系统能够对机器学习推理的过程给出解释,因此在金融,医疗等安全攸关系统(Safety-critical System)中得到大量应用。 5 | 最后,我们会介绍强化学习系统,这一类系统可以帮助计算机和人类进行自动化决策,是实现通用人工智能的关键基础设施。 6 | 7 | 机器学习系统作为一个蓬勃发展的领域,我们也会在不远的将来看到更多相关系统的崛起。我们也欢迎社区贡献更多的章节进入拓展篇,如有想法可以和本书的编辑们联系。 -------------------------------------------------------------------------------- /chapter_programming_interface/development_history.md: -------------------------------------------------------------------------------- 1 | ## 机器学习系统编程模型的演进 2 | 3 | ![机器学习编程库发展历程](../img/ch02/framework_development_history.svg) 4 | :width:`800px` 5 | :label:`img_framedh` 6 | 7 | 随着机器学习系统的诞生,如何设计易用且高性能的API接口就一直成为了系统设计者首要解决的问题。在早期的机器学习框架中(如 :numref:`img_framedh`所示),人们选择用Lua(Torch)和Python(Theano)等高层次编程语言来编写机器学习程序。这些早期的机器学习框架提供了机器学习必须的模型定义,自动微分等功能,其适用于编写小型和科研为导向的机器学习应用。 8 | 9 | 深度神经网络在2011年来快速崛起,很快在各个AI应用领域(计算机视觉、语音识别、自然语言处理等)取得了突破性的成绩。训练深度神经网络需要消耗大量的算力,而以Lua和Python为主导开发的Torch和Theano无法发挥这些算力的最大性能。与此同时,计算加速卡(如英伟达GPU)的通用API接口(例如CUDA C)日趋成熟,且构建于CPU多核技术之上的多线程库(POSIX Threads)也被广大开发者所接受。因此,许多的机器学习用户希望基于C和C++来开发高性能的深度学习应用。这一类需求被Caffe等一系列以C和C++作为核心API的框架所满足。 10 | 11 | 然而,机器学习模型往往需要针对部署场景、数据类型、识别任务等需求进行深度定制,而这类定制任务需要被广大的AI应用领域开发者所实现。这类开发者的背景多样,往往不能熟练使用C和C++。因此Caffe这一类与C和C++深度绑定的编程框架,成为了制约框架快速推广的巨大瓶颈。 12 | 13 | 在2015年底,谷歌率先推出了TensorFlow。相比于传统的Torch,TensorFlow提出前后端分离相对独立的设计,利用高层次编程语言Python作为面向用户的主要前端语言,而利用C和C++实现高性能后端。大量基于Python的前端API确保了TensorFlow可以被大量的数据科学家和机器学习科学家接受,同时帮助TensorFlow能够快速融入Python为主导的大数据生态(大量的大数据开发库如Numpy、Pandas、SciPy、Matplotlib和PySpark)。同时,Python具有出色的和C/C++语言的互操作性,这种互操作性已经在多个Python库中得到验证。因此,TensorFlow兼有Python的灵活性和生态,同时也通过C/C++后端得以实现高性能。这种设计在日后崛起的PyTorch、MindSpore和PaddlePaddle等机器学习框架得到传承。 14 | 15 | 随着各国大型企业开源机器学习框架的出现,为了更高效地开发机器学习应用,基于开源机器学习框架为后端的高层次库Keras和TensorLayerX应运而生,它们提供Python API 可以快速导入已有的模型,这些高层次API进一步屏蔽了机器学习框架的实现细节,因此Keras和TensorLayerX可以运行在不同的机器学习框架之上。 16 | 17 | 随着深度神经网络的进一步发展,对于机器学习框架编程接口的挑战也日益增长。因此在2020年前后,新型的机器学习框架如MindSpore和JAX进一步出现。其中,MindSpore在继承了TensorFlow、PyTorch的Python和C/C++的混合接口的基础上,进一步拓展了机器学习编程模型从而可以高效支持多种AI后端芯片(如华为Ascend、英伟达GPU和ARM芯片),实现了机器学习应用在海量异构设备上的快速部署。 18 | 19 | 同时,超大型数据集和超大型深度神经网络崛起让分布式执行成为了机器学习编程框架的核心设计需求。为了实现分布式执行,TensorFlow和PyTorch的使用者需要花费大量代码来将数据集和神经网络分配到分布式节点上,而大量的AI开发人员并不具有分布式编程的能力。因此MindSpore进一步完善了机器学习框架的分布式编程模型的能力,从而让单节点的MindSpore程序可以无缝地运行在海量节点上。 20 | 21 | 在本小节中,我们将以MindSpore作为例子讲解一个现代机器学习框架的Python前端API和C/C++后端API的设计原则。这些设计原则和PyTorch,TensorFlow相似。 22 | -------------------------------------------------------------------------------- /chapter_programming_interface/index.md: -------------------------------------------------------------------------------- 1 | # 编程接口 2 | 3 | 现代机器学习框架包含大量的组件,辅助用户高效开发机器学习算法、处理数据、部署模型、性能调优和调用硬件加速器。在设计这些组件的应用编程接口(Application Programming Interface,API)时,一个核心的诉求是:如何平衡框架性能和易用性?为了达到最优的性能,开发者需要利用硬件亲和的编程语言如:C和C++来进行开发。这是因为C和C++可以帮助机器学习框架高效地调用硬件底层API,从而最大限度发挥硬件性能。同时,现代操作系统(如Linux和Windows)提供丰富的基于C和C++的API接口(如文件系统、网络编程、多线程管理等),通过直接调用操作系统API,可以降低框架运行的开销。 4 | 5 | 从易用性的角度分析,机器学习框架的使用者往往具有丰富的行业背景(如数据科学家、生物学家、化学家、物理学家等)。他们常用的编程语言是高层次脚本语言:Python、Matlab、R和Julia。相比于C和C++,这些语言在提供编程易用性的同时,丧失了C和C++对底层硬件和操作系统进行深度优化的能力。因此,机器学习框架的核心设计目标是:具有易用的编程接口来支持用户使用高层次语言,如Python实现机器学习算法;同时也要具备以C和C++为核心的低层次编程接口来帮助框架开发者用C和C++实现大量高性能组件,从而在硬件上高效执行。在本章中,将讲述如何达到这个设计目标。 6 | 7 | 本章的学习目标包括: 8 | 9 | - 理解机器学习系统的工作流和以Python为核心的编程接口设计。 10 | 11 | - 理解机器学习系统以神经网络模块为核心的接口设计原理和实现。 12 | 13 | - 理解机器学习系统的底层C/C++执行算子的实现和与上层Python接口的调用实现。 14 | 15 | - 了解机器学习系统编程接口的演进方向。 16 | 17 | ```toc 18 | :maxdepth: 2 19 | 20 | development_history 21 | ml_workflow 22 | neural_network_layer 23 | c_python_interaction 24 | ml_programming_paradigm 25 | summary 26 | ``` -------------------------------------------------------------------------------- /chapter_programming_interface/ml_programming_paradigm.md: -------------------------------------------------------------------------------- 1 | ## 机器学习框架的编程范式 2 | ### 机器学习框架编程需求 3 | 机器学习的训练是其任务中最为关键的一步,训练依赖于优化器算法来描述。目前大部分机器学习任务都使用一阶优化器,因为一阶方法简单易用。随着机器学习的高速发展,软硬件也随之升级,越来越多的研究者开始探索收敛性能更好的高阶优化器。常见的二阶优化器如牛顿法、拟牛顿法、AdaHessians,均需要计算含有二阶导数信息的Hessian矩阵,Hessian矩阵的计算带来两方面的问题,一方面是计算量巨大如何才能高效计算,另一方面是高阶导数的编程表达。 4 | 5 | 同时,近年来,工业界发布了非常多的大模型,从2020年OpenAI GTP-3 175B参数开始,到2021年盘古大模型100B、鹏程盘古-$\alpha$ 200B、谷歌switch transformer 1.6T、智源悟道 1.75T参数,再到2022年百度ERNIE3.0 280M、Facebook NLLB-200 54B,越来越多的超大规模模型训练需求使得单纯的数据并行难以满足,而模型并行需要靠人工来模型切分耗时耗力,如何自动并行成为未来机器学习框架所面临的挑战。最后,构建机器学习模型本质上是数学模型的表示,如何简洁表示机器学习模型也成为机器学习框架编程范式的设计的重点。 6 | 7 | 为了解决机器学习框架在实际应用中的一些困难,研究人员发现函数式编程能很好地提供解决方案。在计算机科学中,函数式编程是一种编程范式,它将计算视为数学函数的求值,并避免状态变化和数据可变,这是一种更接近于数学思维的编程模式。神经网络由连接的节点组成,每个节点执行简单的数学运算。通过使用函数式编程语言,开发人员能够用一种更接近运算本身的语言来描述这些数学运算,使得程序的读取和维护更加容易。同时,函数式语言的函数都是相互隔离的,使得并发性和并行性更容易管理。 8 | 9 | 因此,机器学习框架使用函数式编程设计具有以下优势: 10 | - 支持高效的科学计算和机器学习场景。 11 | - 易于开发并行。 12 | - 简洁的代码表示能力。 13 | 14 | ### 机器学习框架编程范式现状 15 | 本小节将从目前主流机器学习框架发展历程来看机器学习框架对函数式编程的支持现状。谷歌在2015年发布了TensorFlow1.0其代表的编程特点包括计算图(Computational Graphs)、会话(Session)、张量(Tensor)它是一种声明式编程风格。2017年Facebook发布了PyTorch其编程特点为即时执行,它是一种命令式编程风格。2018年谷歌发布了JAX它不是存粹为了机器学习而编写的框架,而是针对GPU和TPU做高性能数据并行计算的框架;与传统的机器学习框架相比其核心能力是神经网络计算和数值计算的融合,在接口上兼容了NumPy、Scipy等Python原生的数据科学接口,而且在此基础上扩展分布式、向量化、高阶求导、硬件加速,其编程风格是函数式,主要体现在无副作用、Lambda闭包等。2020年华为发布了MindSpore,其函数式可微分编程架构可以让用户聚焦机器学习模型数学的原生表达。2022年PyTorch推出functorch,受到谷歌JAX的极大启发,functorch是一个向PyTorch添加可组合函数转换的库,包括可组合的vmap(向量化)和autodiff转换,可与PyTorch模块和PyTorch autograd一起使用,并具有良好的渴望模式(Eager-Mode)性能,functorch可以说是弥补了PyTorch静态图的分布式并行需求。 16 | 17 | 从主流的机器学习框架发展历程来看,未来机器学习框架函数式编程风格将会日益得到应用,因为函数式编程能更直观地表达机器学习模型,同时对于自动微分、高阶求导、分布式实现也更加方便。另一方面,未来的机器学习框架在前端接口层次也趋向于分层解耦,其设计不直接为了机器学习场景,而是只提供高性能的科学计算和自动微分算子,更高层次的应用如机器学习模型开发则是通过封装这些高性能算子实现。 18 | 19 | ### 函数式编程案例 20 | 在上一小节介绍了机器学习框架编程范式的现状,不管是JAX、MindSpore还是functorch都提到了函数式编程,其在科学计算、分布式方面有着独特的优势。然而在实际应用中纯函数式编程几乎没有能够成为主流开发范式,而现代编程语言几乎不约而同的选择了接纳函数式编程特性。以MindSpore为例,MindSpore选择将函数式和面向对象编程融合,兼顾用户习惯,提供易用性最好,编程体验最佳的混合编程范式。MindSpore采用混合编程范式道理也很简单,纯函数式会让学习曲线陡增,易用性变差;面向对象构造神经网络的编程范式深入人心。 21 | 22 | 下面中提供了使用MindSpore编写机器学习模型训练的全流程。其网络构造,满足面向对象编程习惯,函数式编程主要体现在模型训练的反向传播部分;MindSpore使用函数式,将前向计算构造成function,然后通过函数变换,获得grad function,最后通过执行grad function获得权重对应的梯度。 23 | 24 | ```python 25 | # Class definition 26 | class Net(nn.Cell): 27 | def __init__(self): 28 | ...... 29 | def construct(self, inputs): 30 | ...... 31 | 32 | # Object instantiation 33 | net = Net() # network 34 | loss_fn = nn.CrossEntropyLoss() # loss function 35 | optimizer = nn.Adam(net.trainable_params(), lr) # optimizer 36 | 37 | # define forward function 38 | def forword_fn(inputs, targets): 39 | logits = net(inputs) 40 | loss = loss_fn(logits, targets) 41 | return loss, logits 42 | 43 | # get grad function 44 | grad_fn = value_and_grad(forward_fn, None, optim.parameters, has_aux=True) 45 | 46 | # define train step function 47 | def train_step(inputs, targets): 48 | (loss, logits), grads = grad_fn(inputs, targets) # get values and gradients 49 | optimizer(grads) # update gradient 50 | return loss, logits 51 | 52 | for i in range(epochs): 53 | for inputs, targets in dataset(): 54 | loss = train_step(inputs, targets) 55 | ``` -------------------------------------------------------------------------------- /chapter_programming_interface/summary.md: -------------------------------------------------------------------------------- 1 | ## 总结 2 | 3 | - 现代机器学习系统需要兼有易用性和高性能,因此其一般选择Python作为前端编程语言,而使用C和C++作为后端编程语言。 4 | 5 | - 一个机器学习框架需要对一个完整的机器学习应用工作流进行编程支持。这些编程支持一般通过提供高层次Python API来实现。 6 | 7 | - 数据处理编程接口允许用户下载,导入和预处理数据集。 8 | 9 | - 模型定义编程接口允许用户定义和导入机器学习模型。 10 | 11 | - 损失函数接口允许用户定义损失函数来评估当前模型性能。同时,优化器接口允许用户定义和导入优化算法来基于损失函数计算梯度。 12 | 13 | - 机器学习框架同时兼有高层次Python API来对训练过程,模型测试和调试进行支持。 14 | 15 | - 复杂的深度神经网络可以通过叠加神经网络层来完成。 16 | 17 | - 用户可以通过Python API定义神经网络层,并指定神经网络层之间的拓扑来定义深度神经网络。 18 | 19 | - Python和C之间的互操作性一般通过CType等技术实现。 20 | 21 | - 机器学习框架一般具有多种C和C++接口允许用户定义和注册C++实现的算子。这些算子使得用户可以开发高性能模型,数据处理函数,优化器等一系列框架拓展。 22 | 23 | ## 扩展阅读 24 | 25 | - MindSpore编程指南:[MindSpore](https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.6/index.html) 26 | - Python和C/C++混合编程:[Pybind11](https://pybind11.readthedocs.io/en/latest/basics.html#creating-bindings-for-a-simple-function) -------------------------------------------------------------------------------- /chapter_recommender_system/index.md: -------------------------------------------------------------------------------- 1 | # 深度学习推荐系统 2 | 3 | 推荐模型通过对用户特征、物品特征、用户-物品历史交互行为等数据的分析,为用户推荐可能感兴趣的内容、商品或者广告[^1]。在信息爆炸的时代,高效且准确的推荐结果能够极大地提升用户在使用服务时的体验。近年来,基于深度学习的推荐模型[^2] 由于可以高效地从海量数据中发掘用户的潜在兴趣,被谷歌、脸书、阿里巴巴等各大公司广泛应用于生产环境中。为了支持推荐模型的稳定高质量服务,人们围绕其搭建了一系列组件,这些组件和推荐模型共同构成了庞大而又精巧的深度学习推荐系统。本章主要介绍以深度学习模型为中心的推荐系统的基本组成、运行原理以及其在在线环境中面临的挑战和对应的解决方案。 4 | 5 | ```toc 6 | :maxdepth: 2 7 | 8 | system_architecture 9 | multi_stage_recommender_system 10 | model_update 11 | case_study 12 | summary 13 | ``` 14 | 15 | [^1]: 以下统称为“物品” 16 | 17 | [^2]: 以下推荐模型特指基于深度学习的推荐模型 -------------------------------------------------------------------------------- /chapter_recommender_system/model_update.md: -------------------------------------------------------------------------------- 1 | ## 模型更新 2 | 通过以上两节的学习,我们了解了推荐系统的基本组件和运行流程。然而在实际的生产环境中,因为种种原因,推荐系统必须经常性地对模型参数进行更新。在保证上亿在线用户的使用体验的前提下,更新超大规模推荐模型是极具挑战性的。本节首先介绍为何推荐系统需要持续更新模型参数,然后介绍一种主流的离线更新方法,以及一个支持在线更新的推荐系统。 3 | 4 | ### 持续更新模型的需求 5 | 在学习过程中,我们用到的数据集通常都是静态的,例如ImageNet :cite:`russakovsky2015imagenet`,WikiText :cite:`merity2016pointer`。其中的数据分布通常是不变的,因此训练一个模型使其关键指标,如准确率(Accuracy)和困惑度(Perplexity),达到一定要求之后训练任务就结束了。然而在线服务中使用的推荐模型需要面临高度动态的场景。这里的动态主要指两个方面: 6 | 7 | 1. 推荐模型所服务的用户和所囊括的物品是在不断变化的,每时每刻都会有新的用户和新的物品。如图 :numref:`user-embedding-missing`所示,如果嵌入表中没有新用户所对应的嵌入项,那么推荐模型就很难服务于这个用户;同理如果新加入的物品没有在推荐模型的嵌入表中,如图 :numref:`content-embedding-missing`所示,就无法出现在推荐流水线中,从而导致不能被推荐给目标用户。 8 | 2. 推荐模型所面临的用户兴趣是在不断变化的,如果推荐模型不能及时地改变权重以适应用户新的兴趣,那么推荐效果就会下降。例如在一个新闻推荐的应用中,每天的热点新闻都是不一样的,如果推荐模型总是推荐旧的热点,用户的点击率就会持续下降。 9 | 10 | 11 | ![用户嵌入项缺失](../img/ch10/ch-recsys/user_embedding_missing.png) 12 | :width:`800px` 13 | :label:`user-embedding-missing` 14 | 15 | ![物品嵌入项缺失](../img/ch10/ch-recsys/content_embedding_missing.png) 16 | :width:`800px` 17 | :label:`content-embedding-missing` 18 | 19 | 20 | 21 | 以上问题虽然也可以通过人工制定的规则来处理,例如,在直接在推荐结果中加入新物品,或者基于统计的热点物品,但是这些规则只能在短时间内一定程度上缓解问题,而不能彻底解决问题,因为基于人工规则的推荐性能和推荐模型存在较大差距。 22 | 23 | ### 离线更新 24 | 传统的推荐系统采用基于模型检查点的离线更新的方式,更新频率从每天到每小时不等,如图 :numref:`offline-update`所示。 25 | 26 | ![离线更新](../img/ch10/ch-recsys/offline_update.png) 27 | :width:`800px` 28 | :label:`offline-update` 29 | 30 | 具体来讲,在训练一段时间之后,有如下步骤: 31 | 32 | 1. 从训练数据中心的参数服务器上保存一份模型检查点到磁盘中; 33 | 2. 基于离线数据集对模型检查点进行验证,如果离线验证不通过则继续训练; 34 | 3. 如果离线验证通过,则将检查点以广播的方式发送到所有的推理数据中心。 35 | 36 | 这一流程耗费的时间从数分钟到数小时不等。也有一些系统对保存和发送检查点的过程进行了优化,可以做到分钟级模型更新。 37 | 38 | 然而随着互联网服务的进一步发展,分钟级的模型更新间隔在一些场景下依然是远远不够的: 39 | 40 | 1. 一些应用非常看重其中物品的实时性。例如在短视频推荐场景下,内容创作者可能会根据实时热点创作视频,如果这些视频不能被及时推荐出去,等热点稍过观看量可能会远远不及预期。 41 | 2. 无法获取用户特征或者特征有限的场景。近年来,随着用户隐私保护意识的增长和相关数据保护法规的完善,用户常常倾向于匿名使用应用,或者尽量少地提供非必要的数据。这就使得推荐系统需要在用户使用的这段极短的时间内时间内在线学习到用户的兴趣。 42 | 3. 需要使用在线训练范式的场景。传统的推荐系统通常采用离线训练的方式,即累计一段时间(例如,一天)的训练数据来训练模型,并将训练好的模型在低峰期(例如,凌晨)上线。最近越来越多的研究和实践表明,增大训练频率可以有效提升推荐效果。将训练频率增加到最高的结果就是在线训练,即流式处理训练数据并送给模型,模型持续地基于在线样本调整参数,模型更新被即时用于服务于用户。模型更新作为在线训练的一个主要环节,必须要降低延迟以达到更好的训练效果。 43 | 44 | 在下一小节,我们将详细分析一个前沿的推荐系统是如何解决模型快速更新的问题的。 -------------------------------------------------------------------------------- /chapter_recommender_system/summary.md: -------------------------------------------------------------------------------- 1 | ## 小结 2 | 3 | 推荐系统作为深度学习在工业界最成功的落地成果之一,极大地提升了用户的在线使用体验,并且为各大公司创造了可观的利润,从而促使各大公司持续加大对推荐系统的投入。过去两年推荐模型的规模成指数增长,带来了许多系统层面的挑战亟待解决。在实际的生产环境中面临的问题与挑战是本章区区几千字难以概括的,因此工业级推荐系统的架构必然十分复杂,本章只能抛砖引玉地简单介绍一种典型的推荐系统组成的基本架构和运行过程,并介绍了推荐系统面临的持续更新模型的挑战和一种前沿的解决方案。面对实际生产环境,具体的系统设计方案需要根据不同推荐场景的需求而变化,不存在一种万能的解决方案。 4 | 5 | ## 扩展阅读 6 | 7 | - 推荐模型:[Wide & Deep](https://arxiv.org/abs/1606.07792) 8 | 9 | - 消息队列介绍:[什么是消息队列](https://aws.amazon.com/message-queue/) 10 | 11 | - 特征存储介绍:[什么是机器学习中的特征存储](https://www.featurestore.org/what-is-a-feature-store) 12 | 13 | ## 参考文献 14 | 15 | :bibliography:`../references/recommender.bib` -------------------------------------------------------------------------------- /chapter_reinforcement_learning/distributed_node_rl.md: -------------------------------------------------------------------------------- 1 | ## 分布式强化学习系统 2 | 3 | 分布式强化学习系统是比上面介绍的单节点强化学习系统更强大的一种。它能支持多环境多模型并行处理,主要是能同时在多个实际计算机系统上对多个模型进行更新,将大大提高强化学习系统的学习速度和整体表现。我们这里介绍分布式强化学习常见的算法和系统。 4 | 5 | 异步优势行动-批判者(Asynchronous Advantage Actor-Critic,A3C)是由DeepMind研究人员 :cite:`mnih2016asynchronous`于2016年提出的可以在多个计算设备上并行更新网络的学习算法。相比于 :numref:`ch12/ch12-rlzoo`中的单节点强化学习系统,A3C通过创建一组工作者(Worker),并将每个工作者分配到不同的计算设备上且为他们各自创建可以交互的环境来实现并行采样和模型更新,同时用一个主(Master)节点维护这些行动者(Actor)和批判者(Critic)网络的更新。行动者是策略网络,批判者是价值网络,分别对应强化学习中的策略和价值函数。通过这样的设计,整个算法的各个工作者可以实时将所采集到样本计算出的梯度回传到主节点,来更新主节点的模型参数,并在主节点模型更新后即时下发到各个工作者进行模型更新。每个工作者可以单独在一个 GPU 上进行运算,从而整个算法可以在一个 GPU 集群上并行更新模型,算法结构由 :numref:`ch12/ch12-a3c`所示。研究表明,分布式强化学习训练除加速模型学习之外,由于其更新梯度是由多个计算节点各自对环境采样计算得到的,还有利于稳定学习表现。 6 | 7 | ![A3C分布式算法架构](../img/ch12/ch12-a3c.png) 8 | 9 | :width:`800px` 10 | 11 | :label:`ch12/ch12-a3c` 12 | 13 | 重要性加权行动-学习者架构(Importance Weighted Actor-Learner Architecture,IMPALA) 是由Lasse Espeholt等人于2018年 :cite:`espeholt2018impala`提出的能够实现多机集群训练的强化学习框架,如:numref:`ch12/ch12-impala`所示。与 A3C 算法类似,IMPALA 能够在多个 GPU 上并行进行梯度计算。具体地,IMPALA 并行多个行动者(Actor)和学习者(Learner),每个行动者包含一个策略网络,并用这个策略网络与一个环境进行交互,以收集样本。所收集到的样本轨迹由行动者发送到各自的学习者,进行梯度计算。所有的学习者中有一个称为主学习者,它可以和其他所有学习者通信获取他们计算的梯度,从而在主学习者内部对模型进行更新,随后下发到各个学习者及行动者,做新一轮的采样和梯度计算。IMPALA 被证明是比 A3C 更高效的分布式计算架构,它同时得益于一个特殊设计的学习者内的梯度计算函数,称为 V-轨迹目标(V-trace Target),通过重要性加权来稳定训练。我们这里侧重对分布式强化学习结构的介绍,对此不再赘述。感兴趣的读者可以参考原论文 14 | 15 | ![IMPALA分布式算法架构](../img/ch12/ch12-impala.png) 16 | 17 | :width:`800px` 18 | 19 | :label:`ch12/ch12-impala` 20 | 21 | 以上是两个著名的分布式强化学习算法A3C和IMPALA,最近研究中还有许多其他成果,如SEED :cite:`espeholt2019seed`、Ape-X :cite:`horgan2018distributed`等都对分布式强化学习有更好的效果,我们不再做过多介绍。下面我们将讨论几个典型的分布式强化学习算法库。 22 | 23 | ![RLlib系统架构](../img/ch12/ch12-rllib-arch.svg) 24 | 25 | :width:`800px` 26 | 27 | :label:`ch12/ch12-rllib` 28 | 29 | Ray :cite:`moritz2018ray`是由伯克利大学几名研究人员发起的一个分布式计算框架,基于Ray之上构建了一个专门针对强化学习的系统RLlib :cite:`liang2017ray`。RLlib 是一个面向工业级应用的开源强化学习框架,同时 30 | 包含了强化学习的算法库,没有太多强化学习经验的人也可以很方便地使用 RLlib。 31 | 32 | ![RLlib分布式训练](../img/ch12/ch12-rllib-distributed.svg) 33 | 34 | :width:`600px` 35 | 36 | :label:`ch12/ch12-rllib_dist` 37 | 38 | RLlib的系统架构如 :numref:`ch12/ch12-rllib`所示,系统底层是构建在 Ray 的分布式计算和通信的基础组建之 39 | 上,面向强化学习的领域概念,在 Python 层抽象了 Trainer, Environment, Policy 等基础组件,并为各个抽象组件提供了一些常用的内置实现,同时用户可以根据自己的算法场景对组件进行扩展,通过这些内置以及自定义的算法组件,研究人员可以方便快速地实现具体的强化学习算法。RLlib支持多种范式的分布式强化学习训练,如 :numref:`ch12/ch12-rllib_dist`所示为基于同步采样的强化学习算法的分布式训练架构。其中每一个 Rollout Worker 为一个独立进程,负责和对应的环境进行交互以完成经验采集,多个 Rollout Worker 可以并行地完成环境交互;Trainer 负责 Rollout Worker之间的协调,策略优化,以及将更新后的策略同步到 Rollout Worker 中。 40 | 41 | 强化学习中的策略通常可以采用深度神经网络,而基于深度神经网络的分布式强化学习训练,可以采用 RLlib 结合 PyTorch 或者 TensorFlow 等深度学习框架协同完成,深度学习框架负责策略网络的训练和更新,RLlib 负责强化学习的算法计算。此外 RLlib 支持与并行的向量化(Vectorized)环境交互,允许外接模拟器,以及可以进行离线(Offline)强化学习。 42 | 43 | 对于分布式系统中样本回放缓冲池的管理,我们会提到另一个工作Reverb :cite:`cassirer2021reverb`。回忆本章开头,我们介绍了强化学习中的状态、动作、奖励等概念,实际强化学习算法进行训练所使用的数据正是存放在经验缓冲池中的这些数据元组,而每种数据自身的格式可能又有不同,实际使用时也需要对不同的数据做不同类型的操作。常见的数据操作类型如拼接、截取、乘积、转置、部分乘积、取均值、取极值等,而每种操作都可能需要对特定数据的特定维度进行,这常常给现有的强化学习框架在实践中产生一定的困难。为了方便强化学习过程中灵活使用不同的数据形式,Reverb 设计了数据块的概念(Chunks),所有使用的训练数据在缓冲池中都使用数据块的格式进行管理和调用,这一设计基于数据是多维张量的特点,增大了数据使用的灵活性和访问速度。Acme :cite:`hoffman2020acme`是近年来由DeepMind提出的一个分布式强化学习框架,同样是针对学术界的研究和工业界的应用,它基于 Reverb 对样本缓冲池的数据管理,结合分布式采样的结构,给出了一个更快的分布式强化学习解决方案。Reverb 帮助解决了数据管理和传输的效率问题,使得 Acme得以将分布式计算的效力充分发挥,研究人员用 Acme 在大量强化学习基准测试中取得了显著的速度提升。 -------------------------------------------------------------------------------- /chapter_reinforcement_learning/index.md: -------------------------------------------------------------------------------- 1 | # 强化学习系统 2 | 3 | 在本章中,我们介绍深度学习的一个重要分支——强化学习及其在系统方面的知识。本章的学习目标包括: 4 | 5 | - 掌握强化学习基本知识。 6 | 7 | - 掌握单节点和多节点强化学习系统设计思路。 8 | 9 | - 掌握多智能体强化学习基础知识及系统设计简介。 10 | 11 | ```toc 12 | :maxdepth: 2 13 | 14 | rl_introduction 15 | single_node_rl 16 | distributed_node_rl 17 | marl 18 | marl_sys 19 | summary 20 | ``` 21 | -------------------------------------------------------------------------------- /chapter_reinforcement_learning/marl.md: -------------------------------------------------------------------------------- 1 | ## 多智能体强化学习 2 | 3 | 以上所讲述的强化学习内容都为单智能体强化学习,而在近来的强化学习研究中,多智能体强化学习越来越受到研究人员关注。回想在本小节初介绍的单智能体强化学习框架 :numref:`ch12/ch12-rl-framework`,其中我们只有单个智能体产生的单个动作对环境产生影响,环境也返回单个奖励值给智能体。这里我们把单智能体强化学习扩展到多智能体强化学习,可以得到至少两种可能的多智能体强化学习框架,如 :numref:`ch12/ch12-marl`所示。 :numref:`ch12/ch12-marl`(a)为多智能体同时执行动作的情况,他们相互之间观察不到彼此的动作,他们的动作一同对环境产生影响,并各自接受自己动作所产生的奖励。 :numref:`ch12/ch12-marl`(b)为多智能体顺序执行动作的情况,后续智能体可能观察到前序智能体的动作,他们的动作一同对环境产生影响,并接受到各自的奖励值或共同的奖励值。除此之外,还有许多其他可能的多智能体框架,如更复杂的智能体间观察机制、智能体间通讯机制、多智能体合作与竞争等等。同时,这里假设多个智能体对环境的观察量都为环境的状态,这是最简单的一种,也是现实中最不可能出现的一种,实际情况下的多智能体往往对环境有各自不同的观察量。![两种可能的多智能体强化学习框架:(a)同步式多智能体决策;(b)异步式多智能体决策。](../img/ch12/ch12-marl.png) 4 | 5 | :width:`800px` 6 | 7 | :label:`ch12/ch12-marl` 8 | 9 | 这里我们可以根据前面对单智能体强化学习过程的马尔可夫决策过程描述,给出多智能体强化学习的马尔可夫决策过程,它可以用一个数组$(\mathcal{S}, N, \boldsymbol{\mathcal{A}}, \mathbf{R}, \mathcal{T}, \gamma)$来表示。$N$是智能体个数,$\mathcal{S}$和$\boldsymbol{\mathcal{A}}=(\mathcal{A}_1, \mathcal{A}_2, ..., \mathcal{A}_N)$分别是环境状态空间和多智能体动作空间,其中$A_i$是第$i$个智能体的动作空间,$\mathbf{R}=(R_1, R_2, ..., R_N)$是多智能体奖励函数,$\mathbf{R}(s,\mathbf{a})$: $\mathcal{S}\times \boldsymbol{\mathcal{A}}\rightarrow \mathbb{R}^N$为对于当前状态$s\in\mathcal{S}$和当前多智能体动作$\mathbf{a}\in\boldsymbol{\mathcal{A}}$的奖励向量值,其中$R_i$是对第$i$个智能体的奖励值。从当前状态和动作到下一个状态的状态转移概率定义为$\mathcal{T}(s^\prime|s,\mathbf{a})$: $\mathcal{S}\times\boldsymbol{\mathcal{A}}\times\mathcal{S}\rightarrow \mathbb{R}_+$。$\gamma\in(0,1)$是奖励折扣因子(假设多个智能体采用相同的奖励折扣因子)。不同于单智能体强化学习,多智能体强化学习的目标除了常见的最大化每个智能体各自的期望累计奖励值$\mathbb{E}[\sum_t \gamma^t r^i_t], i\in[N]$之外,还有许多其他可能的学习目标,如达到纳什均衡、最大化团队奖励等等。 10 | 11 | 由上述介绍和定义可以发现,多智能体强化学习是一个比单智能体强化学习更加复杂的问题。而实际上,多个智能体的存在,对于每个智能体的决策而言,绝对不是简单的把每个单智能体决策累加的难度,实际情况要比单智能体决策问题复杂很多。多智能体系统的研究实际上是门古老的学科,它与博弈论(Game Theory)密切相关,在深度强化学习盛行以前早已有大量研究和许多理论上未解的难题。其中一个典型的问题是纳什均衡在双人非零和博弈下没有多项式时间内可解的方法(实际上,这是一个PPAD(Polynomial Parity Argument, Directed version)类的问题。(见论文Settling the Complexity of Computing Two-Player Nash Equilibria. Xi Chen, et al.)由于篇幅限制,我们这里无法对多智能体问题做深入探讨,我们可以用一个简单例子来介绍为什么多智能体强化学习问题无法简单地用单智能体强化学习算法来解。 12 | 13 | :剪刀-石头-布的奖励值表 14 | 15 | | 奖励值 | 剪刀 | 石头 | 布 | 16 | | --- | ------- | ------- | ------- | 17 | | **剪刀** | (0,0) | (-1,+1) | (+1,-1) | 18 | | **石头** | (+1,-1) | (0,0) | (-1,+1) | 19 | | **布** | (-1,+1) | (+1,-1) | (0,0) | 20 | |:label:`tab_ch12_ch12_marl`|||| 21 | 22 | 我们考虑一个大家都熟悉的游戏, 剪刀-石头-布,考虑两个玩家玩这个游戏的输赢情况,我们知道有这样的输赢关系:剪刀<石头<布<剪刀...这里的“<”即前一个纯策略被后一个纯策略完全压制,我们给予奖励值-1、+1到这两个玩家,当他们选择相同的纯策略时,奖励值均为0。于是我们得到一个奖励值表如 :numref:`tab_ch12_ch12_marl`所示,横轴为玩家1,纵轴为玩家2,表内的数组为玩家1和玩家2各自在相应动作下得到的奖励值。 23 | 24 | 由于这个矩阵的反对称性,这个问题的纳什均衡策略对两个玩家相同,均为$(\frac{1}{3}, \frac{1}{3}, \frac{1}{3})$的策略分布,即有各$\frac{1}{3}$的概率出剪刀、石头或布。如果我们把得到这个纳什均衡策略作为多智能体学习的目标,那么我们可以简单分析得到这个均衡策略无法通过简单的单智能体算法得到。考虑我们随机初始化两个玩家为任意两个纯策略,比如玩家1出剪刀,玩家2出石头。这时假设玩家2策略固定,可以把玩家2看做固定环境的一部分,于是可以使用任意单智能体强化学习算法对玩家1进行训练,使其最大化自己的奖励值。于是,玩家1会收敛到布的纯策略。这时再把玩家1固定,训练玩家2,玩家2又收敛到剪刀的纯策略。于是循环往复,整个训练过程始终无法收敛,玩家1和2各自在3个策略中循环却无法得到正确的纳什均衡策略。 25 | 26 | 27 | ![自学习算法示意图。](../img/ch12/ch12-marl-sp.png) 28 | 29 | :width:`600px` 30 | 31 | :label:`ch12/ch12-marl-sp` 32 | 33 | 我们在上面这个例子中采用的学习方法其实是多智能体强化学习中最基础的一种,叫自学习(Selfplay),如 :numref:`ch12/ch12-marl-sp`所示。自学习的方法即固定当前玩家 1 的策略,按照单智能体优化的方法最大化一侧智能体的表现,所得策略称为最佳反应策略(Best Response Strategy)。之后再将这一最佳反应策略作为玩家 2 的固定策略,再来优化另一边的智能体策略,如此循环。我们可以看到自学习在特定的任务设置下可能无法收敛到我们想要的最终目标。正是由于多智能体学习过程中有类似循环结构的出现,我们需要更复杂的训练方法,和专门针对多智能体的学习方式来达到我们想要的目标。 34 | 35 | 一般来讲,多智能体强化学习是比单智能体强化学习更复杂的一类,对于自学习的方法而言,单智能体强化学习的过程可以看做一个多智能体强化学习的子任务。从前面这一小游戏的角度来理解,当玩家 1 策略固定时,玩家 1 加游戏环境构成玩家 2 的实际学习环境,由于这个环境是固定的,玩家 2 可以通过单智能体强化学习来达到自身奖励值最大化;这时再固定玩家 2 的策略,玩家 1 又可以进行单智能体强化学习...... 这样,单智能体强化学习是多智能体任务的子任务。如 :numref:`ch12/ch12-marl-fsp`,其他算法如虚构自学习(Fictitious Self-play),需要在每个单智能体强化学习的步骤中,对对手历史策略的平均策略求得最优应对策略,而对手的训练也是如此,进行循环,能够在上面剪刀-石头-布一类的游戏中保证收敛到纳什均衡策略。 36 | 37 | ![虚构自学习算法示意图。](../img/ch12/ch12-marl-fsp.png) 38 | 39 | :width:`600px` 40 | 41 | :label:`ch12/ch12-marl-fsp` -------------------------------------------------------------------------------- /chapter_reinforcement_learning/rl_introduction.md: -------------------------------------------------------------------------------- 1 | ## 强化学习介绍 2 | 3 | 近年来,强化学习作为机器学习的一个分支受到越来越多的关注。2013 年 DeepMind 公司的研究人员提出了深度 Q 学习 :cite:`mnih2013playing`(Deep Q-learning),成功让 AI 从图像中学习玩电子游戏。自此以后,以 DeepMind 为首的科研机构推出了像 AlphaGo 围棋 AI 这类的引人瞩目的强化学习成果,并在 2016 年与世界顶级围棋高手李世石的对战中取得了胜利。自那以后,强化学习领域连续取得了一系列成就,如星际争霸游戏智能体 AlphaStar、Dota 2 游戏智能体 OpenAI Five、多人零和博弈德州扑克的 Pluribus、机器狗运动控制算法等。在这一系列科研成就的背后,是整个强化学习领域算法在这些年内快速迭代进步的结果,基于模拟器产生的大量数据使得对数据“饥饿”(Data Hungry)的深度神经网络能够表现出很好的拟合效果,从而将强化学习算法的能力充分发挥出来,在以上领域中达到或者超过人类专家的学习表现。目前,强化学习已经从电子游戏逐步走向更广阔的应用场景,如机器人控制、机械手灵巧操作、能源系统调度、网络负载分配、股票期货交易等一系列更加现实和富有意义的领域,对传统控制方法和启发式决策理论发起冲击。 4 | 5 | ![强化学习框架](../img/ch12/ch12-rl.png) 6 | 7 | :width:`400px` 8 | 9 | :label:`ch12/ch12-rl-framework` 10 | 强化学习的核心是不断地与环境交互来优化策略从而提升奖励的过程,主要表现为基于某个**状态**(State)下的**动作**(Action)的选择。进行这一决策的对象我们常称为**智能体**(Agent),而这一决策的影响将在**环境**(Environment)中体现。更具体地,不同的决策会影响环境的**状态转移**(State Transition)和**奖励**(Reward)。以上状态转移是环境从当前状态转移到下一状态的函数,它可以是确定性也可以是随机性的。奖励是环境对智能体动作的反馈,通常是一个标量。以上过程可以抽象为 :numref:`ch12/ch12-rl-framework`所示,这是文献中最常见的强化学习的模型描述。 11 | 12 | 举例来说,当人在玩某个电子游戏的时候,需要逐渐熟悉游戏的操作以取得更好的游戏结果,那么人从刚接触到这个游戏到逐步掌握游戏技巧的这个过程为一个类似于强化学习的过程。该游戏从开始后的任一时刻,会处于一个特定的状态,而人通过观察这个状态会获得一个**观察量**(Observation)(如观察游戏机显示屏的图像),并基于这个观察量做出一个操作动作(如发射子弹),这一动作将改变这个游戏下一时刻的状态,使其转移到下一个状态(如把怪物打败了),并且玩家可以知道当前动作的效果(如产生了一个正或负的分数,怪物打败了则获得正分数)。这时玩家再基于下一个状态的观察量做出新的动作选择,周而复始,直到游戏结束。通过反复的操作和观察,人能够逐步掌握这个游戏的技巧,一个强化学习智能体也是如此。 13 | 14 | 这里注意,有几个比较关键的问题:一是观察量未必等于状态,而通常观察量是状态的函数,从状态到观察量的映射可能有一定的信息损失。对于观察量等于状态或者根据观察量能够完全恢复环境状态的情况,我们称为**完全可观测**(Fully Observable),否则我们称为**部分可观测**(Partially Observable)环境;二是玩家的每个动作未必会产生立即反馈,某个动作可能在许多步之后才产生效果,强化学习模型允许这种延迟反馈的存在;三是这种反馈对人的学习过程而言未必是个数字,但是我们对强化学习智能体所得到的反馈进行数学抽象,将其转变为一个数字,称为奖励值。奖励值可以是状态的函数,也可以是状态和动作的函数,依具体问题而定。奖励值的存在是强化学习问题的一个基本假设,也是现有强化学习与监督式学习的一个主要区别 15 | 16 | 强化学习的决策过程通常由一个马尔可夫决策过程(Markov Decision Process,MDP)(马尔可夫决策过程即一个后续状态只依赖当前状态和动作而不依赖于历史状态的函数)描述,可以用一个数组$(\mathcal{S}, \mathcal{A}, R, \mathcal{T}, \gamma)$来表示。$\mathcal{S}$和$\mathcal{A}$分别是状态空间和动作空间,$R$是奖励函数,$R(s,a)$: $\mathcal{S}\times \mathcal{A}\rightarrow \mathbb{R}$为对于当前状态$s\in\mathcal{S}$和当前动作$a\in\mathcal{A}$的奖励值。从当前状态和动作到下一个状态的状态转移概率定义为$\mathcal{T}(s^\prime|s,a)$: $\mathcal{S}\times\mathcal{A}\times\mathcal{S}\rightarrow \mathbb{R}_+$。$\gamma\in(0,1)$是奖励折扣因子(折扣因子可以乘到每个后续奖励值上,从而使无穷长序列有有限的奖励值之和)。强化学习的目标是最大化智能体的期望累计奖励值$\mathbb{E}[\sum_t \gamma^t r_t]$。 17 | 18 | 马尔可夫决策过程中的马尔可夫性质由以下定义 19 | 20 | $$ 21 | \mathcal{T}(s_{t+1}|s_t) = \mathcal{T}(s_{t+1}|s_0, s_1, s_2, \dots, s_t) 22 | $$ 23 | 24 | 即当前状态转移只依赖于上一时刻状态,而不依赖于整个历史。这里的状态转移函数$\mathcal{T}$中省略了动作$a$,马尔可夫性质是环境转移过程的属性,其独立于产生动作的决策过程。 25 | 26 | 基于马尔可夫性质,可以进一步推导出在某一时刻最优策略不依赖于整个决策历史,而只依赖于当前最新状态的结论。这一结论在强化学习算法设计中有着重要意义,它简化了最优策略的求解过程。 27 | 28 | -------------------------------------------------------------------------------- /chapter_reinforcement_learning/single_node_rl.md: -------------------------------------------------------------------------------- 1 | ## 单节点强化学习系统 2 | 3 | 前面介绍了强化学习的基本知识,这里我们介绍常见的单智能体强化学习系统中较为简单的一类,即单节点强化学习系统,这里的节点是指一个用于模型更新的计算单元。我们按照是否对模型更新的过程做并行化处理,将强化学习系统分为单节点和分布式强化学习系统。其中,单节点强化学习系统可以理解为只实例化一个类对象作为智能体,与环境交互进行采样和利用所采得的样本进行更新的过程分别视为这个类内的不同函数。除此之外的更为复杂的强化学习框架都可视为分布式强化学习系统。 4 | 5 | 分布式强化学习系统的具体形式有很多,系统的形式也往往依赖于所实现的算法。从最简单的情况考虑,假设我们仍在同一个计算单元上实现算法,但是将强化学习的采样过程和更新过程实现为两个并行的进程,甚至各自实现为多个进程,以满足不同计算资源间的平衡。这时就需要进程间通信来协调采样和更新过程,这是一个最基础的分布式强化学习框架。更为复杂的情况是,整个算法的运行在多个计算设备上进行(如一个多机的计算集群),智能体的函数可能需要跨机跨进程间的通信来实现。对于多智能体系统,还需要同时对多个智能体的模型进行更新,则需要更为复杂的计算系统设计。我们将逐步介绍这些不同的系统内的实现机制。 6 | 7 | 我们先对单节点强化学习系统进行介绍。在这里,我们以RLzoo :cite:`ding2020efficient`为例,讲解一个单节点强化学习系统构建所需要的基本模块。如 :numref:`ch12/ch12-rlzoo`所示,是RLzoo算法库中采用的一个典型的单节点强化学习系统,它包括几个基本的组成部分:神经网络、适配器、策略网络和价值网络、环境实例、模型学习器、经验回放缓存(Experience Replay Buffer)等。 8 | 9 | 我们先对前三个,神经网络、适配器、策略网络和价值网络进行介绍。神经网络即一般深度学习中的神经网络,用于实现基于数据的函数拟合,我们在图中简单列出常见的三类神经网络:全连接网络,卷积网络和循环网络。策略网络和价值网络是一般深度强化学习的常见组成部分,策略网络即一个由深度神经网络参数化的策略表示,而价值网络为神经网络表示的状态价值(State-Value)或状态-动作价值(State-Action Value)函数。这里我们不妨称前三类神经网络为一般神经网络,策略网络和价值网络为强化学习特定网络,前者往往是后者的重要组成部分。在RLzoo中,适配器则是为实现强化学习特定网络而选配一般神经网络的功能模块。首先,根据不同的观察量类型,强化学习智能体所用的神经网络头部会有不同的结构,这一选择可以由一个基于观察量的适配器来实现;其次,根据所采用的强化学习算法类型,相应的策略网络尾部需要有不同的输出类型,包括确定性策略和随机性策略,RLzoo 中使用一个策略适配器来进行选择;最后,根据不同的动作输出,如离散型、连续型、类别型等,需要使用一个动作适配器来选择。:numref:`ch12/ch12-rlzoo`中我们统称这三个不类型的适配器为适配器。 10 | 11 | 介绍完这些,我们已经有了可用的策略网络和价值网络,这构成了强化学习智能体核心学习模块。除此之外,还需要一个学习器(Learner)来更新这些学习模块,更新的规则就是强化学习算法给出的损失函数。而要想实现学习模块的更新,最重要的是输入的学习数据,即智能体跟环境交互过程中所采集的样本。对于**离线**(Off-Policy)强化学习,这些样本通常被存储于一个称为经验回放缓存的地方,学习器在需要更新模型时从该缓存中采得一些样本来进行更新。这里说到的离线强化学习是强化学习算法中的一类,强化学习算法可以分为在线(On-Policy)强化学习和离线(Off-Policy)强化学习两类,按照某个特定判据。这个判据是,用于更新的模型和用于采样的模型是否为同一个,如果是,则称在线强化学习算法,否则为离线强化学习算法。因而,离线强化学习通常允许与环境交互所采集的样本被存储于一个较大的缓存内,从而允许在许久之后再从这个缓存中抽取样本对模型进行更新。而对于在线强化学习,这个“缓存”有时其实也是存在的,只不过它所存储的是非常近期内采集的数据,从而被更新模型和用于采样的模型可以近似认为是同一个。从而,这里我们简单表示 RLzoo 的强化学习系统统一包括这个经验回放缓存模块。有了以上策略和价值网络、经验回放缓存、适配器、学习器,我们就得到了 RLzoo 中一个单节点的强化学习智能体,将这个智能体与环境实例交互,并采集数据进行模型更新,我们就得到了一个完整的单节点强化学习系统。这里的环境实例化我们允许多个环境并行采样。 12 | 13 | ![RLzoo算法库中使用的强化学习系统](../img/ch12/ch12-rlzoo.png) 14 | 15 | :width:`800px` 16 | 17 | :label:`ch12/ch12-rlzoo` 18 | 近来研究人员发现,强化学习算法领域的发展瓶颈,可能不仅在于算法本身,而在于让智能体在其中采集数据的模拟器的模拟速度。Isaac Gym :cite:`makoviychuk2021isaac`是Nvidia公司于2021年推出的基于GPU(Graphics Processing Unit)的模拟引擎,在单GPU上实现2-3倍于之前基于CPU(Central Processing Unit)的模拟器的运行速度。关于 GPU上运行加速我们已经在章节 5 中有所介绍。之所以 GPU 模拟能够对强化学习任务实现显著的加 19 | 速效果,除了 GPU 本身多核心的并行运算能力之外,还在于这省却了 CPU 与 GPU 之间的数据传输和通信时间。传统的强化学习环境,如 OpenAI Gym(这是一个常用的强化学习基准测试环境)等,都是基于 CPU 进行的模拟计算,而深度学习方法的神经网络训练通常是在 GPU 或TPU(Tensor Processing Unit) 上进行的。 20 | 21 | 从智能体与 CPU 上实例化的模拟环境交互过程所收集的数据样本,通常先暂时以 CPU 的数据格式存储,在使用的时候被转移到 GPU 上成为具有 GPU 数据类型的数据(如使用 PyTorch 时可通过tensor.to(device)的函数实现,只需将device设为“cuda”即可将一个类型为torch.Tensor的tensor转移到GPU上),然后来进行模型训练。同时,由于模型参数是以 GPU 上数据的类型存储的,调用模型进行前向传递的过程中也需要先将输入数据从 CPU 转移到 GPU 上,并且可能需要将模型输出的 GPU 数据再转移回 CPU 类型。这一系列冗余的数据转换操作都会显著增长模型学习的时间,并且也增加了算法实际使用过程中的工程量。Isaac Gym 模拟器的设计从模拟器下层运行硬件上解决了这一困难,由于模拟器和模型双双实现在 GPU 上,他们之间的数据通信不再需要通过 CPU 来实现,从而绕过了 CPU 与 GPU 数据双向传输这一问题,实现了对强化学习任务中模拟过程的特定加速。 -------------------------------------------------------------------------------- /chapter_reinforcement_learning/summary.md: -------------------------------------------------------------------------------- 1 | ## 小结 2 | 3 | 在这一章,我们简单介绍了强化学习的基本概念,包括单智能体和多智能体强化学习算法、单节点和分布式强化学习系统等,给读者对强化学习问题的基本认识。当前,强化学习是一个快速发展的深度学习分支,许多实际问题都有可能通过强化学习算法的进一步发展得到解决。另一方面,由于强化学习问题设置的特殊性(如需要与环境交互进行采样等),也使得相应算法对计算系统的要求更高:如何更好地平衡样本采集和策略训练过程?如何均衡 CPU 和 GPU 等不同计算硬件的能力?如何在大规模分布式系统上有效部署强化学习智能体?都需要对计算机系统的设计和使用有更好的理解。 4 | 5 | ## 参考文献 6 | 7 | :bibliography:`../references/reinforcement.bib` -------------------------------------------------------------------------------- /chapter_rl_sys/control.md: -------------------------------------------------------------------------------- 1 | ## 控制系统 2 | 3 | 虽然控制理论已牢牢植根于基于模型(Model-based)的设计思想,但丰富的数据和机器学习方法给控制理论带来了新的机遇。控制理论和机器学习的交叉方向涵盖了广泛的研究方向以及在各种现实世界系统中的应用。 4 | 5 | ### 线性二次控制 6 | 7 | 理论方面,线性二次控制(Linear-Quadratic Control)是经典的控制方法。若动力系统可以用一组线性微分方程表示,而其约束为二次泛函,这类的问题称为线性二次问题。此类问题的解即为线性二次调节器(Linear–Quadratic Regulator),简称LQR。最近有关于图神经网络在分布式线性二次控制的研究,将线性二次问题转换为自监督学习问题,能够找到基于图神经网络的最佳分布式控制器,他们还推导出了所得闭环系统稳定的充分条件。 8 | 9 | ### 模型预测控制 10 | 11 | 模型预测控制(MPC)是一种先进的过程控制方法,用于在满足一组约束条件的同时控制过程。MPC 的主要优势在于它允许优化当前时刻的同时考虑未来时刻。因此与线性二次调节器不同。MPC 还具有预测未来事件的能力,并可以相应地采取控制措施。最近有研究将最优控制和机器学习相结合并应用在陌生环境中的视觉导航任务:比如基于学习的感知模块产生一系列航路点通过无碰撞路径引导机器人到达目标,基于模型的规划器使用这些航路点来生成平滑且动态可行的轨迹,然后使用反馈控制在物理系统上执行。实验表明,与纯粹基于几何映射或基于端到端学习的方案相比,这种新的系统可以更可靠、更有效地到达目标位置。 12 | 13 | ### 控制系统的稳定性分析 14 | 15 | 因为安全对机器人应用是至关重要的,有的强化学习方法通过学习动力学的不确定性来提高安全性,鼓励安全、稳健、以及可以正式认证所学控制策略的方法,如 图:numref:`safe\_learning\_control`展示了安全学习控制(Safe Learning Control)系统的框架图。Lyapunov 函数是评估非线性动力系统稳定性的有效工具,最近有人提出Neural Lyapunov来将安全性纳入考虑。 16 | 17 | ![安全学习控制系统,数据被用来更新控制策略或或安全滤波器 :cite:`brunke2021safe`](../img/ch13/safe_learning_control.png) 18 | 19 | :width:`800px` 20 | 21 | :label:`safe\_learning\_control` 22 | 23 | -------------------------------------------------------------------------------- /chapter_rl_sys/control_code_ex.md: -------------------------------------------------------------------------------- 1 | ## 控制系统案例 2 | 3 | 在上一章节中,我们初步了解了机器人的控制系统,同时也知道了机器学习在机器人控制系统这个领域有着很多有趣和有前景的研究方向。 4 | 只不过由于控制系统的复杂性和这些研究的前瞻性,它们不太适合用来作为简单的案例。 5 | 6 | 与此同时,ROS作为一个成熟的机器人框架,它已经包含了很多成熟稳定的经典控制组件。 7 | 这些控制组件和其他的成熟的功能模块一起组成了更大规模的功能模组,来完成更复杂的任务。 8 | 9 | 在这些更大规模的功能模组中,**Nav2**和**MoveIt2**可能是最常用的两个。 10 | 11 | 从名字上就可以看出来,这两个功能模组各自都是它们ROS1版本的继承者。 12 | Nav2是ROS Navigation Stack在ROS2中的继承者,专注于移动机器人的导航相关的功能,例如定位,路径规划等,并致力于用安全的方式将机器人从一点移动到另一点。 13 | MoveIt2是ROS MoveIt在ROS2中的继承者,致力于打造一个容易使用的机器人操纵平台。带机械臂的机器人都基本离不开它。 14 | 15 | 这两个模组都成熟,可靠,和容易使用。使用ROS框架开发机器人是基本上都会直接使用它们或者在它们已有功能的基础上做适合自己的自定义修改,以避免重复造轮子。 16 | 17 | 因此,在本章节中,我们将以Nav2为案例,来带领大家初步了解怎样使用一个大型的ROS2功能模组。 18 | 19 | 本章节的内容很大程度参考了Nav2的[英文官方文档](https://navigation.ros.org/),尤其是“Getting Started”这一章。对自己英文有信心的读者可以尝试阅读官方文档以了解更多细节。 20 | 21 | 本章没有额外的代码案例。 22 | 23 | ### 安装 24 | 25 | 首先,让我们通过Ubuntu的库管理器来安装Nav2相关的程序库。 26 | 27 | ```shell 28 | sudo apt install ros-foxy-navigation2 ros-foxy-nav2-bringup 29 | ``` 30 | 31 | 其中`ros-foxy-navigation2`是Nav2的核心程序库,而`ros-foxy-nav2-bringup`则是Nav2的一个启动案例。 32 | 这个案例十分灵活,很多时候我们可以将其稍加修改后放到自己的项目中使用。 33 | 34 | 接下来让我们安装`turtlebot3`相关的一系列程序库。 35 | turtlebot系列是一个很成功的入门级移动机器人系列。 36 | 而这一系列程序库则提供了和turtlebot3机器人相关的组件,其中包含了在模拟环境中使用虚拟turtlebot3机器人的相关功能组件。 37 | 38 | ```shell 39 | sudo apt install "ros-foxy-turtlebot3*" 40 | ``` 41 | 42 | ### 运行 43 | 44 | 在安装好上面的那些程序库后,我们就可以尝试使用Nav2了。 45 | 46 | 首先,让我们新开一个终端窗口,并执行以下命令。这些命令分别导入了ROS2框架,并设定好了我们要使用哪个Turtlebot3模型和在哪儿搜索虚拟世界(Gazebo)需要的模型。 47 | 48 | ```shell 49 | source /opt/ros/foxy/setup.bash 50 | export TURTLEBOT3_MODEL=waffle 51 | export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:/opt/ros/foxy/share/turtlebot3_gazebo/models 52 | ``` 53 | 54 | 现在,我们一切就绪,可以下面这行命令来运行一个Nav2的演示程序。 55 | 56 | ```shell 57 | ros2 launch nav2_bringup tb3_simulation_launch.py 58 | ``` 59 | 60 | 其中`ros2 launch`命令是用来执行一个launch文件,而后者则是将很多需要启动的ROS2组件集合到一起来按计划启动的一个说明文件。 61 | 一个机器人项目经常需要启动很多个不同的组件来配合完成任务。 62 | 而如果每个组件都要新开一个窗口执行命令的话,整个机器人的启动将会变得十分繁琐。 63 | launch文件和`ros2 launch`命令就是来解决这个问题的。 64 | 我们可以把整个ROS2项目想象成一个交响乐团,其中每个组件分别代表一个乐器。 65 | 而launch文件就像是乐团的指挥,负责调配每个乐器应该在什么时候启动。 66 | 总而言之,这是ROS2中一个非常使用的特性。 67 | 68 | 关于`ros2 launch`命令和launch文件的更多细节,感兴趣的读者可以查阅[官方英文文档](https://docs.ros.org/en/foxy/Tutorials/Launch/Creating-Launch-Files.html)。 69 | 70 | 成功运行上述命令之后,我们应该会看到两个新开的GUI窗口,分别对应`RViz`和`Gazebo`程序。 71 | 其中`RViz`是ROS2框架的可视化接口,我们稍后将通过它来控制我们的虚拟机器人。 72 | 而`Gazebo`则是一个用过创建和运行虚拟世界的软件。 73 | 它独立于ROS2框架,但两者又互相紧密合作。 74 | 75 | 在`Gazebo`窗口中(如下图所示),我们应该能够看到一个三维的类六边形虚拟世界。 76 | 这个世界中还有一个虚拟的Turtlebot3机器人。 77 | 这个机器人发射出很多蓝色的射线。 78 | 这些射线代表了机器人的激光雷达的读数射线。 79 | 而激光雷达的读数则被Nav2用来在环境中定位机器人。 80 | 81 | ![Gazebo 截图 1](../img/ch13/ros2-gazebo-1.JPG) 82 | 83 | 在`RViz`窗口中(如下图所示),我们应该能够看到虚拟世界的一个二维地图。 84 | 地图上的白色部分是机器人可以到达的部分,而黑色则是检测到的障碍物或墙。 85 | 如果你在左侧看到有红色的`Global Status: Error`错误的话,你的机器人并没有在RViz(即ROS2框架)中正确的定位。 86 | 请在工具栏选择`2D Pose Estimate`并在RViz地图上机器人应该在的位置(以Gazebo中机器人的位置为准)更新好机器人的姿态。 87 | 88 | ![RViz 截图 1](../img/ch13/ros2-rviz-1.JPG) 89 | 90 | 更新好机器人的姿态后,RViz应该和下图比较相似。 91 | 92 | ![RViz 截图 2](../img/ch13/ros2-rviz-2.JPG) 93 | 94 | 这样一来,我们的机器人就准备好在虚拟事件中移动了。 95 | 96 | 请在RViz的工具栏中选择`Navigation2 Goal`按钮,并在地图上选择你想要Turtlebot3机器人最终所到达的位置和姿态。 97 | 一旦选好了,你将会看到机器人开始向目标位置移动并最终到达目标。 98 | 99 | RViz还提供了很多其它的Nav2功能的按钮,你可以通过Nav2和ROS2的官方英文文档来了解更多使用方法。 100 | 101 | 恭喜,你现在初步了解了怎样使用ROS2框架内的大型功能模组! 102 | 103 | #### 章节附录:在WSL中使用Nav2 104 | 105 | 有些读者可能是通过Windows下的WSL(Windows Subsystem for Linux)来运行ROS2的。 106 | 如果是这种情况,这一章节中的图形界面程序,如RViz和Gazebo,可能会造成问题。 107 | 这是因为WSL默认并不能打开图形界面程序。 108 | 109 | 幸运的是,我们可以更改设置来达到在WSL中运行图形界面程序这一点。 110 | [这篇笔记](https://github.com/rhaschke/lecture/wiki/WSL-install)介绍了其作者是如何在WSL中运行ROS2和图形界面的。其中第二点尤为值得注意。 111 | 而[这篇笔记](https://github.com/cascadium/wsl-windows-toolbar-launcher#firewall-rules)则更为细致的介绍了在一般情况下怎样在WSL中运行图形界面程序。 112 | 113 | 这两篇笔记应该可以给读者足够的信息来解决上述所说的和RViz还有Gazebo相关的问题。唯一的缺点就是这两篇笔记都是英文的,对读者的英语水平有一定要求。 -------------------------------------------------------------------------------- /chapter_rl_sys/index.md: -------------------------------------------------------------------------------- 1 | # 机器人系统 2 | 3 | 本章介绍机器学习的一个重要分支——机器人及其在系统方面的知识,学习目标包括: 4 | 5 | - 掌握机器人系统基本知识。 6 | 7 | - 掌握感知系统、规划系统和控制系统。 8 | 9 | - 掌握通用机器人操作系统。 10 | 11 | ```toc 12 | :maxdepth: 2 13 | 14 | rl_sys_intro 15 | ros 16 | ros_code_ex 17 | summary 18 | ``` 19 | -------------------------------------------------------------------------------- /chapter_rl_sys/perception.md: -------------------------------------------------------------------------------- 1 | ## 感知系统 2 | 3 | 感知系统不仅包括视觉感知,还可以包含触觉、声音等。在未知环境中,机器人想实现自主移动和导航必须知道自己在哪(通过相机重定位 :cite:`ding2019camnet`),周围什么情况(通过3D物体检测 :cite:`yi2020segvoxelnet`或语义分割),预测相机在空间的轨迹 :cite:`9813561`,这些要依靠感知系统来实现 :cite:`xu2019depth`。 4 | 一提到感知系统,不得不提的就是即时定位与建图(Simultaneous Localization 5 | and 6 | Mapping,SLAM)系统。SLAM大致过程包括地标提取、数据关联、状态估计、状态更新以及地标更新等。视觉里程计Visual 7 | Odometry是SLAM中的重要部分,它估计两个时刻机器人的相对运动(Ego-motion)。ORB-SLAM系列是视觉SLAM中有代表性的工作, :numref:`orbslam3` 展示了最新的ORB-SLAM3的主要系统组件。香港科技大学开源的基于单目视觉与惯导融合的SLAM技术VINS-Mono也很值得关注。多传感器融合、优化数据关联与回环检测、与前端异构处理器集成、提升鲁棒性和重定位精度都是SLAM技术接下来的发展方向。 8 | 9 | 最近,随着机器学习的兴起,基于学习的SLAM框架也被提了出来。TartanVO是第一个基于学习的视觉里程计(VO)模型,该模型可以推广到多个数据集和现实世界场景,并优于传统基于几何的方法。 10 | UnDeepVO是一个无监督深度学习方案,能够通过使用深度神经网络估计单目相机的 11 | 6-DoF 位姿及其视图深度。DROID-SLAM是用于单目、立体和 12 | RGB-D 相机的深度视觉 SLAM,它通过Bundle 13 | Adjustment层对相机位姿和像素深度的反复迭代更新,具有很强的鲁棒性,故障大大减少,尽管对单目视频进行了训练,但它可以利用立体声或 14 | RGB-D 视频在测试时提高性能。其中,Bundle Adjustment 15 | (BA)与机器学习的结合被广泛研究。CMU提出通过主动神经 16 | SLAM 17 | 的模块化系统帮助智能机器人在未知环境中的高效探索。 18 | 19 | ### 物体检测与语义分割 20 | 21 | 感知系统不仅包括视觉感知,还可以包含触觉、声音等。在未知环境中,机器人想实现自主移动和导航必须知道自己在哪(通过相机重定位 :cite:`ding2019camnet`),周围什么情况(通过3D物体检测 :cite:`yi2020segvoxelnet`或语义分割),预测相机在空间的轨迹 :cite:`9813561`,这些要依靠感知系统来实现 :cite:`xu2019depth`。 22 | 23 | 图像语义分割作为一项常用而又经典的感知技术,经过多年不停的迭代,传统的2D技术已经渐渐的趋于成熟,提升空间较小。同时传统的2D语义分割有一定的局限性,很难从2D图像中直接获知物体的空间位置、以及其在整体空间中的布局,要知道整体空间的位置信息还是需要更多的三维信息。为了让机器人从单纯的2D图像出发,得到空间中物体三维的坐标、语义和边界信息,跨视角语义分割 :cite:`9123682`吸引了众多研究者的关注。 24 | 25 | ### 即时定位与建图(SLAM) 26 | 27 | 将一个机器人放到未知的环境中,如何能让它明白自己的位置和周围环境?这要靠即时定位与建图(Simultaneous Localization and Mapping,SLAM)系统来实现。 28 | 29 | 图:numref:`orbslam3` 展示了最新的ORB-SLAM3的主要系统组件。 30 | SLAM大致过程包括地标提取、数据关联、状态估计、状态更新以及地标更新等。SLAM系统在机器人运动过程中通过重复观测到的地图特征(比如,墙角,柱子等)定位自身位置和姿态,再根据自身位置增量式的构建地图,从而达到同时定位和地图构建的目的。 31 | 32 | DROID-SLAM是用于单目、立体和 RGB-D 相机的深度视觉 SLAM,它通过Bundle Adjustment层对相机位姿和像素深度的反复迭代更新,具有很强的鲁棒性,故障大大减少,尽管对单目视频进行了训练,但它可以利用立体声或 RGB-D 视频在测试时提高性能。 33 | 其中,Bundle Adjustment (BA)描述了像素坐标和重投影坐标之间误差的和,重投影坐标通常使用3D坐标点和相机参数计算得到。BA计算量较大较为耗时,爱丁堡大学提出通过分布式多GPU系统 :cite:`MegBA` 对BA计算进行加速。随着机器学习的发展,BA与机器学习的结合被广泛研究。 34 | 35 | 视觉里程计Visual Odometry是SLAM中的重要部分,它估计两个时刻机器人的相对运动。 36 | 最近,随着机器学习的兴起,基于学习的VO框架也被提了出来。 37 | TartanVO是第一个基于学习的视觉里程计(VO)模型,该模型可以推广到多个数据集和现实世界场景,并优于传统基于几何的方法。 38 | 39 | ![ORB-SLAM3主要系统组件 :cite:`campos2021orb`](../img/ch13/orbslam3.png) 40 | 41 | :width:`800px` 42 | 43 | :label:`orbslam3` 44 | 45 | -------------------------------------------------------------------------------- /chapter_rl_sys/planning.md: -------------------------------------------------------------------------------- 1 | ## 规划系统 2 | 3 | 机器人规划不仅包含运动路径规划,还包含任务规划 :cite:`9712373` :cite:`wang2023mimicplay`,:cite:`li2023behavior`。其中,运动规划是机器人技术的核心问题之一,在给定的两个位置之间为机器人找到一条符合约束条件的路径。这个约束可以是无碰撞、路径最短、机械功最小等,需要有概率完整性和最优性的保证,从导航到复杂环境中的机械臂操作都有运动规划的应用。然而,当经典运动规划在处理现实世界的机器人问题(在高维空间中)时,挑战仍然存在。研究人员仍在开发新算法来克服这些限制,包括优化计算和内存负载、更好地规划表示和处理维度灾难等。 4 | 5 | 同时,机器学习的一些进展为机器人专家研究运动规划问题开辟了新视角:以数据驱动的方式解决经典运动规划器的瓶颈。基于深度学习的规划器可以使用视觉或语义输入进行规划等。ML4KP是一个可用于运动动力学进行运动规划的C++库,可以轻松地将机器学习方法集成到规划过程中。 6 | 7 | 8 | 强化学习在规划系统上也有重要应用 :cite:`sun2021adversarial`,最近有一些工作基于MetaDrive模拟器 :cite:`li2021metadrive`进行多智能体强化学习、驾驶行为分析等 :cite:`peng2021learning` :cite:`peng2021safe` :cite:`li2021efficient`。为了更好地说明强化学习是如何应用在自动驾驶中,尤其是作为自动驾驶规划模块的应用, 图:numref:`rl\_ad`展示了一个基于深度强化学习的自动驾驶POMDP模型,包含环境、奖励、智能体等重要组件。 9 | 10 | ![基于深度强化学习的自动驾驶POMDP模型 :cite:`aradi2020survey`](../img/ch13/rl_ad.png) 11 | 12 | :width:`800px` 13 | 14 | :label:`rl\_ad` 15 | -------------------------------------------------------------------------------- /chapter_rl_sys/robot_safety.md: -------------------------------------------------------------------------------- 1 | ## 在机器人项目中安全的应用机器学习 2 | 3 | 机器人和机器学习都是有广阔前景和令人兴奋的前沿领域,而当它们结合在一起后,会变得更加迷人,并且有远大于1+1>2的效果。 因此,当我们在机器人项目中应用机器学习时,我们很容易过于兴奋,尝试着用机器学习去做很多之前只能幻想的成果。 然而,在机器人中应用机器学习和直接使用机器学习有着很多不同。 其中很重要的一点不同就是,一般的机器学习系统更多的是在虚拟世界中造成直接影响,而机器人中的机器学习系统很容易通过机器人对物理世界造成直接影响。 因此,**当我们在机器人项目中应用机器学习时,我们必须时刻关注系统的安全性**,保证无论是在产品开发时还是在产品上市后的使用期,开发者和用户的安全性都能得到可靠的保证。 而且不仅商业项目要考虑安全性,开发个人项目是也需要确保安全性。 没有人想因为安全性上的疏忽而对自己或朋友/同事造成无法挽回的遗憾。 4 | 5 | 以上这些并不是危言耸听,让我们设想以下这些情况: 6 | 假设你正在为你们公司开发一个物流仓库内使用的移动货运机器人,它被设计为和工人在同一工作环境内运行,以便在需要时及时帮工人搬运货物至目的地。 这个机器人有一个视觉的行人识别系统,以便识别前方是否有人。 当机器人在前进的过程中遇到障碍物的话,这个行人识别系统会参与决定机器人的行为。 如果有人的话,机器人会选择绕大弯来避开行进道路上的行人障碍物;而如果没人的话,机器人可以绕小弯来避障。 可是,如果某次这个行人识别系统检测失误,系统没有检测到前方的障碍物是一个正在梯子上整理货物的工人,所以选择小弯避障。 而当机器人靠近时,工人才突然发现有个机器人正在靠近他,并因此受到惊吓跌落至机器人行进的正前方。如果我们考虑到物流仓库的货运机器人自重加载重一般至少是几百公斤,我们就知道万一真的因此发生碰撞,后果是不堪设想。 如果真的发生这种情况,这个机器人产品的商业前景会毁于一旦,公司和负责人也会被追究相应责任(甚至法律意义上的责任)。更重要的是,对受害者所造成的伤害和自己心里的内疚会对双方的一生都造成严重的影响。 7 | 8 | 不仅是商业项目,假设你正在开发一个小型娱乐机械臂来尝试帮你完成桌面上的一些小任务,例如移动茶杯或打开关闭开关。 你的这个机械臂也依赖于一个物体识别系统来识别任务目标。 某次在移动茶杯时,机械臂没有识别到规划路线中有一个接线板,因此茶杯不小心摔倒并且水泼到接线板里引起短路。 幸运的话可能只需要换一个接线板,而不幸的时候甚至可能会引起火灾或电击。 我相信,没有人会想遇到这类突发事件。 9 | 10 | 因此,无论是在怎样的机器人项目中应用机器学习,我们都必须时刻关注和确保系统的安全性。 11 | 12 | ### 确保安全性的办法:风险评估和独立的安全系统 13 | 14 | #### 风险评估 15 | 16 | 为了能够确保机器人和机器学习系统的安全性,我们首先要知道可能有哪些危险。 我们可以通过风险评估(Risk Assessment)来做到这一点。 17 | 怎样完成一份风险评估网上已经有很多文章了,我们在这里就不过多的介绍。 我们想要强调的是,对于发现的风险,我们需要尽可能的给出一个避免风险的方案(Risk Mitigation)。 更重要的时,我们需要确保这些方案的具体执行,而不仅仅是流于表面的给出方案就完事。 一份没有执行的方案等于没有方案。 18 | 19 | #### 独立的安全系统 20 | 21 | 在了解了可能有哪些风险之后,我们可以通过设计一个独立的安全系统来规避掉风险中和机器人系统相关的那一部分。 22 | 具体来讲,这个安全系统应该独立于机器学习系统,并且处于机器人架构的底层和拥有足够或最高等级的优先级。 实际上,这个安全系统不应该只针对机器学习系统,而是应该针对整个机器人的方方面面。 或者换句话来说,当开发机器人项目时,必须要有一个足够安全且独立的安全系统。 而针对于机器学习系统的安全性只是这个独立安全系统“足够安全”的部分体现罢了。 23 | 还是以之前的那个物流仓库移动货运机器人为例。 如果机器人的轮子是有独立安全回路并且断电自动刹车的轮子,而机器人又有一个严格符合安全标准且也有安全回路的激光雷达来检测障碍物,同时这个激光雷达的安全回路直接连接至轮子的安全回路。 这样一来,不管机器人是否检测到前方有人或突然有一个人闯入机器人行进路线,激光雷达都会检测到有异物,直接通过独立的安全回路将轮子断电并刹车,以确保不会发生碰撞。 这样一个配置完全独立于任何控制逻辑,从而不受任何上层系统的影响。 **而对于开发者来说,当我们有了一个可靠独立的安全系统,我们也可以放心的去使用最新的突破性技术,而不用担心新技术是否会造成不可预期的后果。** 24 | 25 | ### 机器学习系统的伦理问题 26 | 27 | 除了上述讨论到的最根本的安全性问题,机器学习系统的伦理问题也会对机器人的使用造成影响。 28 | 29 | 例如训练数据集中人种类型不平衡这一类经典的伦理问题。 让我们还是以之前的那个物流仓库移动货运机器人为例。 如果我们的训练数据集只有亚洲人的图片,那么当我们想要开拓海外市场时,我们的海外用户很有可能会发现我们的机器人并不能很好的识别他们的工人。 虽然独立的安全系统可以避免事故的发生,但是急停在工人面前肯定不是一个很好的用户体验。 我们机器人的海外销量也会受到影响。 30 | 31 | 机器学习系统的伦理问题是目前比较火热的一个讨论领域。作为行业相关人员,我们需要了解这个方向上的最新进展。一方面是在系统设计的初期就把这些问题考虑进去,另一方面也是希望我们的成果能够给更多人带来幸福,而不是带去困扰。 -------------------------------------------------------------------------------- /chapter_rl_sys/ros.md: -------------------------------------------------------------------------------- 1 | ## 通用机器人操作系统 2 | 3 | ![ROS/ROS2架构概述 :cite:`maruyama2016exploring`](../img/ch13/ROS2_arch.png) 4 | 5 | :width:`800px` 6 | 7 | :label:`ROS2\_arch` 8 | 9 | 在这一章节中,我们来大致了解一下机器人操作系统(ROS)。机器人操作系统(ROS)起源于斯坦福大学人工智能实验室的一个机器人项目。它是一个自由、开源的框架,提供接口、工具来构建先进的机器人。由于机器人领域的快速发展和复杂化,代码复用和模块化的需求日益强烈,ROS适用于机器人这种多节点多任务的复杂场景。目前也有一些机器人、无人机甚至无人车都开始采用ROS作为开发平台。在机器人学习方面,ROS/ROS2可以与深度学习结合,有开发人员为ROS/ROS2开发了的深度学习节点,并支持NVIDIA Jetson和TensorRT。NVIDIA Jetson是NVIDIA为自主机器开发的一个嵌入式系统,包括CPU、GPU、PMIC、DRAM 和闪存的一个模组化系统,可以将自主机器软件运作系统运行速率提升。TensorRT 是由 Nvidia 发布的机器学习框架,用于在其硬件上运行机器学习推理。 10 | 11 | 作为一个适用于机器人编程的框架,ROS把原本松散的零部件耦合在了一起,为他们提供了通信架构。虽然叫做``操作系统”,ROS更像是一个中间件,给各种基于ROS的应用程序建立起了沟通的桥梁,通过这个中间件,机器人的感知、决策、控制算法可以组织和运行。ROS采用了分布式的设计思想,支持C++、Pyhton等多种编程语言,方便移植。对ROS来讲,最小的进程单元是节点,由节点管理器来管理。参数配置存储在参数服务器中。ROS的通信方式包含:主题(Topic)、服务(Service)、参数服务器(Parameter Server)、动作库(ActionLib)这四种。 12 | 13 | ROS提供了很多内置工具,比如三维可视化器rviz,用于可视化机器人、它们工作的环境和传感器数据。它是一个高度可配置的工具,具有许多不同类型的可视化和插件。catkin是ROS 构建系统(类似于Linux下的CMake),Catkin Workspace是创建、修改、编译Catkin软件包的目录。roslaunch可用于在本地和远程启动多个ROS 节点以及在ROS参数服务器上设置参数的工具。此外还有机器人仿真工具Gazebo和移动操作软件和规划框架MoveIt!。ROS为机器人开发者提供了不同编程语言的接口,比如C++语言ROS接口roscpp,python语言的ROS接口rospy。ROS中提供了许多机器人的统一机器人描述格式URDF(Unified Robot Description Format)文件,URDF使用XML格式描述机器人文件。ROS也有一些需要提高的地方,比如它的通信实时性能有限,与工业级要求的系统稳定性还有一定差距。 14 | 15 | ROS2项目在ROSCon 2014上被宣布,第一个ROS2发行版 Ardent Apalone 于2017年发布。ROS2增加了对多机器人系统的支持,提高了多机器人之间通信的网络性能,而且支持微控制器和跨系统平台,不仅可以运行在现有的X86和ARM系统上,还将支持MCU等嵌入式微控制器,不止能运行在Linux系统之上,还增加了对Windows、MacOS、RTOS等系统的支持。更重要的是,ROS2还加入了实时控制的支持,可以提高控制的时效性和整体机器人的性能。ROS2的通信系统基于DDS(Data Distribution Service),即数据分发服务,如 :numref:`ROS2\_arch`所示。 16 | 17 | ROS2依赖于使用shell环境组合工作区。“工作区”(Workspace)是一个ROS术语,表示使用ROS2进行开发的系统位置。核心ROS2 工作区称为Underlay。随后的工作区称为Overlays。使用ROS2进行开发时,通常会同时有多个工作区处于活动状态。接下来我们详细介绍一下ROS2的核心概念。这一部分我们参考了文献 [^1]。 18 | 19 | ### ROS2节点 20 | 21 | ROS Graph是一个由ROS2元素组成的网络,在同一时间一起处理数据。它包括所有的可执行文件和它们之间的联系。ROS2 中的每个节点都应负责一个单一的模块用途(例如,一个节点用于控制车轮马达,一个节点用于控制激光测距仪等)。每个节点都可以通过主题、服务、动作或参数向其他节点发送和接收数据。一个完整的机器人系统由许多协同工作的节点组成。如 :numref:`ros2\_graph`。在ROS2中,单个可执行文件(C++程序、Python 程序等)可以包含一个或多个节点。 22 | 23 | ![一个完整的机器人系统由许多协同工作的节点组成](../img/ch13/ros2_graph.png) 24 | 25 | :width:`800px` 26 | 27 | :label:`ros2\_graph` 28 | 29 | 节点之间的互相发现是通过ROS2底层的中间件实现的,过程总结如下: 30 | 31 | - 当一个节点启动后,它会向其他拥有相同ROS域名的节点进行广播,说明它已经上线。其他节点在收到广播后返回自己的相关信息,这样节点间的连接就可以建立了,之后就可以通信了。 32 | 33 | - 节点会定时广播它的信息,这样即使它已经错过了最初的发现过程,它也可以和新上线的节点进行连接。 34 | 35 | - 节点在下线前它也会广播其他节点自己要下线了。 36 | 37 | ### ROS2主题 38 | 39 | ROS2将复杂系统分解为许多模块化节点。主题(Topics)是 ROS Graph的重要元素,它充当节点交换消息的总线。如 :numref:`ros2\_topics` 所示,一个节点可以向任意数量的主题发布数据,同时订阅任意数量的主题。主题是数据在节点之间以及因此在系统的不同部分之间移动的主要方式之一。 40 | 41 | rqt是ROS的一个软件框架,以插件的形式实现了各种 GUI 工具。可以在 rqt 中将所有现有的GUI工具作为可停靠窗口运行。这些工具仍然可以以传统的独立方法运行,但rqt可以更轻松地同时管理屏幕上的所有各种窗口。 42 | 43 | ![一个节点可以向任意数量的主题发布数据,同时订阅任意数量的主题](../img/ch13/ros2_topics.png) 44 | 45 | :width:`800px` 46 | 47 | :label:`ros2\_topics` 48 | 49 | ### ROS2服务 50 | 51 | 服务(Services)是 ROS 图中节点的另一种通信方式。服务基于调用和响应模型,而不是主题的发布者-订阅者模型。虽然主题允许节点订阅数据流并获得持续更新,但服务仅在客户端专门调用它们时才提供数据。节点可以使用ROS2中的服务进行通信。与主题那种单向通信模式中节点发布可由一个或多个订阅者使用的信息的方式不同,服务是客户端向节点发出请求的请求/响应模式提供服务,服务处理请求并生成响应,如 :numref:`ros2\_services` 52 | 53 | ![ROS2服务](../img/ch13/ros2_services.png) 54 | 55 | :width:`800px` 56 | 57 | :label:`ros2\_services` 58 | 59 | ### ROS2参数 60 | 61 | 参数(Parameters)是节点的配置值。您可以将参数视为节点设置。节点可以将参数存储为整数、浮点数、布尔值、字符串和列表。在ROS2 中,每个节点都维护自己的参数。 62 | 63 | ### ROS2动作 64 | 65 | 动作(Actions)是ROS2中的一种通信类型,适用于长时间运行的任务。它们由三个部分组成:目标、反馈和结果,如 :numref:`ros2\_actions` 所示。动作建立在主题和服务之上。它们的功能类似于服务,除了可以取消动作。它们还提供稳定的反馈,而不是返回单一响应的服务。动作使用客户端-服务器模型,类似于发布者-订阅者模型。”动作客户端”节点将目标发送到”动作服务器”节点,该节点确认目标并返回反馈流和结果。机器人系统可能会使用动作进行导航。动作目标可以告诉机器人前往某个位置。当机器人导航到该位置时,它可以沿途发送更新(即反馈),然后在到达目的地后发送最终结果消息。 66 | 67 | ![ROS2动作](../img/ch13/ros2_actions.png) 68 | 69 | :width:`800px` 70 | 71 | :label:`ros2\_actions` 72 | 73 | 74 | [^1]: https://docs.ros.org/en/foxy/Tutorials/Understanding-ROS2-Nodes.html 75 | -------------------------------------------------------------------------------- /chapter_rl_sys/summary.md: -------------------------------------------------------------------------------- 1 | ### 总结 2 | 3 | 在这一章,我们简单介绍了机器人系统的基本概念,包括通用机器人操作系统、感知系统、规划系统和控制系统等,给读者对机器人问题的基本认识。对通用机器人操作系统部分,我们回顾了其中的基本概念,并通过代码实例让读者对ROS能有直接的体验,体会到搭建一个简单机器人系统的乐趣。当前,机器人是一个快速发展的人工智能分支,许多实际问题都需要通过机器人算法和系统设计的进一步发展得到解决。 4 | 5 | ## 参考文献 6 | 7 | :bibliography:`../references/rlsys.bib` 8 | -------------------------------------------------------------------------------- /config.ini: -------------------------------------------------------------------------------- 1 | [project] 2 | 3 | name = machine laerning system 4 | 5 | title = 机器学习系统:设计和实现 6 | 7 | author = Luo Mai, Hao Dong 8 | 9 | copyright = 2022, All authors. 10 | 11 | release = 1.0.0 12 | 13 | lang = zh 14 | 15 | [build] 16 | 17 | # A list of wildcards to indicate the markdown files that need to be evaluated as 18 | # Jupyter notebooks. 19 | notebooks = *.md */*.md 20 | 21 | # A list of files that will be copied to the build folder. 22 | resources = img/ references/ 23 | 24 | # Files that will be skipped. 25 | exclusions = */*_origin.md README.md info/* contrib/*md 26 | 27 | # If True (default), then will evaluate the notebook to obtain outputs. 28 | eval_notebook = True 29 | 30 | tabs = mindspore, pytorch, tensorflow 31 | 32 | sphinx_configs = numfig_format = {'figure': '图%%s', 'table': '表%%s', 'code-block': '列表%%s', 'section': '%%s节'} 33 | latex_elements = { 34 | 'utf8extra' : '', 35 | 'inputenc' : '', 36 | 'babel' : r'''\usepackage[english]{babel}''', 37 | 'preamble' : r''' 38 | \usepackage{ctex} 39 | \setmainfont{Source Serif Pro} 40 | \setsansfont{Source Sans Pro} 41 | \setmonofont{Source Code Pro} 42 | \setCJKmainfont[BoldFont=Source Han Serif SC SemiBold]{Source Han Serif SC} 43 | \setCJKsansfont[BoldFont=Source Han Sans SC Medium]{Source Han Sans SC Normal} 44 | \setCJKmonofont{Source Han Sans SC Normal} 45 | \addto\captionsenglish{\renewcommand{\chaptername}{}} 46 | \addto\captionsenglish{\renewcommand{\contentsname}{目录}} 47 | \usepackage[draft]{minted} 48 | \fvset{breaklines=true, breakanywhere=true} 49 | \setlength{\headheight}{13.6pt} 50 | \makeatletter 51 | \fancypagestyle{normal}{ 52 | \fancyhf{} 53 | \fancyfoot[LE,RO]{{\py@HeaderFamily\thepage}} 54 | \fancyfoot[LO]{{\py@HeaderFamily\nouppercase{\rightmark}}} 55 | \fancyfoot[RE]{{\py@HeaderFamily\nouppercase{\leftmark}}} 56 | \fancyhead[LE,RO]{{\py@HeaderFamily }} 57 | } 58 | \makeatother 59 | \CJKsetecglue{} 60 | \usepackage{zhnumber} 61 | ''', 62 | # The font size ('10pt', '11pt' or '12pt'). 63 | 'pointsize': '10pt', 64 | # Latex figure (float) alignment 65 | 'figure_align': 'H', 66 | 'fncychap': '\\usepackage[Sonny]{fncychap}', 67 | } 68 | 69 | 70 | 71 | [html] 72 | 73 | # A list of links that is displayed on the navbar. A link consists of three 74 | # items: name, URL, and a fontawesome icon 75 | # (https://fontawesome.com/icons?d=gallery). Items are separated by commas. 76 | header_links = GitHub, https://github.com/openmlsys/openmlsys-zh, fab fa-github, 77 | English, https://openmlsys.github.io/html-en, fas fa-external-link-alt 78 | 79 | favicon = static/favicon.png 80 | 81 | html_logo = static/logo-with-text.png 82 | 83 | 84 | [pdf] 85 | 86 | # The file used to post-process the generated tex file. 87 | # post_latex = ./static/post_latex/main.py 88 | 89 | latex_logo = static/logo.png 90 | -------------------------------------------------------------------------------- /img/Advanced/preface3_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_1.png -------------------------------------------------------------------------------- /img/Advanced/preface3_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_2.png -------------------------------------------------------------------------------- /img/Advanced/preface3_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_3.png -------------------------------------------------------------------------------- /img/Advanced/preface3_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_4.png -------------------------------------------------------------------------------- /img/Advanced/preface3_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_5.png -------------------------------------------------------------------------------- /img/Advanced/preface3_arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/Advanced/preface3_arc.png -------------------------------------------------------------------------------- /img/ch01/framework-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch01/framework-architecture.png -------------------------------------------------------------------------------- /img/ch01/system-ecosystem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch01/system-ecosystem.png -------------------------------------------------------------------------------- /img/ch03/chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/chain.png -------------------------------------------------------------------------------- /img/ch03/dynamic_gen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/dynamic_gen.png -------------------------------------------------------------------------------- /img/ch03/eager-gen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/eager-gen.png -------------------------------------------------------------------------------- /img/ch03/eager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/eager.png -------------------------------------------------------------------------------- /img/ch03/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/graph.png -------------------------------------------------------------------------------- /img/ch03/if.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/if.png -------------------------------------------------------------------------------- /img/ch03/order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/order.png -------------------------------------------------------------------------------- /img/ch03/recurrent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/recurrent.png -------------------------------------------------------------------------------- /img/ch03/simpledag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/simpledag.png -------------------------------------------------------------------------------- /img/ch03/static.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/static.png -------------------------------------------------------------------------------- /img/ch03/static_gen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/static_gen.png -------------------------------------------------------------------------------- /img/ch03/tensor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/tensor.png -------------------------------------------------------------------------------- /img/ch03/unroll.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/unroll.png -------------------------------------------------------------------------------- /img/ch03/while.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch03/while.png -------------------------------------------------------------------------------- /img/ch04/LLVM基础结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/LLVM基础结构.png -------------------------------------------------------------------------------- /img/ch04/TensorFlow-IR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/TensorFlow-IR.png -------------------------------------------------------------------------------- /img/ch04/中间表示-Jaxpr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-Jaxpr.png -------------------------------------------------------------------------------- /img/ch04/中间表示-LLVMIR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-LLVMIR.png -------------------------------------------------------------------------------- /img/ch04/中间表示-MLIR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-MLIR.png -------------------------------------------------------------------------------- /img/ch04/中间表示-MindIR.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-MindIR.png -------------------------------------------------------------------------------- /img/ch04/中间表示-MindIR图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-MindIR图.png -------------------------------------------------------------------------------- /img/ch04/中间表示-MindIR示例.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-MindIR示例.png -------------------------------------------------------------------------------- /img/ch04/中间表示-torchscript.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-torchscript.png -------------------------------------------------------------------------------- /img/ch04/中间表示-中间表示结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-中间表示结构.png -------------------------------------------------------------------------------- /img/ch04/中间表示-线性中间表示.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/中间表示-线性中间表示.png -------------------------------------------------------------------------------- /img/ch04/符号微分的表达式膨胀问题.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/符号微分的表达式膨胀问题.png -------------------------------------------------------------------------------- /img/ch04/编译器整体流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/编译器整体流程.png -------------------------------------------------------------------------------- /img/ch04/自动微分-前向模式自动微分示例.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/自动微分-前向模式自动微分示例.png -------------------------------------------------------------------------------- /img/ch04/自动微分-反向模式自动微分示例.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/自动微分-反向模式自动微分示例.png -------------------------------------------------------------------------------- /img/ch04/静态分析-静态分析模块.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch04/静态分析-静态分析模块.png -------------------------------------------------------------------------------- /img/ch05/SIMD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/SIMD.png -------------------------------------------------------------------------------- /img/ch05/SIMT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/SIMT.png -------------------------------------------------------------------------------- /img/ch05/combine_memory_reuse_and_no_reuse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/combine_memory_reuse_and_no_reuse.png -------------------------------------------------------------------------------- /img/ch05/compiler-backend-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/compiler-backend-architecture.png -------------------------------------------------------------------------------- /img/ch05/computation_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/computation_graph.png -------------------------------------------------------------------------------- /img/ch05/concat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/concat.png -------------------------------------------------------------------------------- /img/ch05/conv_sum_relu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/conv_sum_relu.png -------------------------------------------------------------------------------- /img/ch05/data_format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/data_format.png -------------------------------------------------------------------------------- /img/ch05/device_malloc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/device_malloc.png -------------------------------------------------------------------------------- /img/ch05/floatdtype.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/floatdtype.png -------------------------------------------------------------------------------- /img/ch05/graph_exec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_1.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_2.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_3.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_4.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_5.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_6.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_7.png -------------------------------------------------------------------------------- /img/ch05/graph_exec_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_exec_8.png -------------------------------------------------------------------------------- /img/ch05/graph_kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/graph_kernel.png -------------------------------------------------------------------------------- /img/ch05/host-device-memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/host-device-memory.png -------------------------------------------------------------------------------- /img/ch05/inplace-op.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/inplace-op.png -------------------------------------------------------------------------------- /img/ch05/matmuldatalayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/matmuldatalayout.png -------------------------------------------------------------------------------- /img/ch05/memory_allocate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/memory_allocate.png -------------------------------------------------------------------------------- /img/ch05/memory_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/memory_architecture.png -------------------------------------------------------------------------------- /img/ch05/memory_fusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/memory_fusion.png -------------------------------------------------------------------------------- /img/ch05/nchw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/nchw.png -------------------------------------------------------------------------------- /img/ch05/nchwandnhwc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/nchwandnhwc.png -------------------------------------------------------------------------------- /img/ch05/parallel_computing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/parallel_computing.png -------------------------------------------------------------------------------- /img/ch05/poly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/poly.png -------------------------------------------------------------------------------- /img/ch05/poly_test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/poly_test.png -------------------------------------------------------------------------------- /img/ch05/select_kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/select_kernel.png -------------------------------------------------------------------------------- /img/ch05/side_effect_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/side_effect_1.png -------------------------------------------------------------------------------- /img/ch05/side_effect_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/side_effect_2.png -------------------------------------------------------------------------------- /img/ch05/single_op_exec.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/single_op_exec.PNG -------------------------------------------------------------------------------- /img/ch05/transdata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch05/transdata.png -------------------------------------------------------------------------------- /img/ch06/6.4/duplicated_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/duplicated_data.png -------------------------------------------------------------------------------- /img/ch06/6.4/hide_global_latency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/hide_global_latency.png -------------------------------------------------------------------------------- /img/ch06/6.4/hide_smem_latency.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/hide_smem_latency.png -------------------------------------------------------------------------------- /img/ch06/6.4/naive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/naive.png -------------------------------------------------------------------------------- /img/ch06/6.4/use_float4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/use_float4.png -------------------------------------------------------------------------------- /img/ch06/6.4/use_smem_load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/use_smem_load.png -------------------------------------------------------------------------------- /img/ch06/6.4/use_smem_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/use_smem_pipeline.png -------------------------------------------------------------------------------- /img/ch06/6.4/use_smem_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/use_smem_store.png -------------------------------------------------------------------------------- /img/ch06/6.4/use_tile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/6.4/use_tile.png -------------------------------------------------------------------------------- /img/ch06/MLIR-Lowing_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/MLIR-Lowing_cn.png -------------------------------------------------------------------------------- /img/ch06/SM_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/SM_cn.png -------------------------------------------------------------------------------- /img/ch06/TBE_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/TBE_cn.png -------------------------------------------------------------------------------- /img/ch06/TVM_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/TVM_cn.png -------------------------------------------------------------------------------- /img/ch06/V100_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/V100_cn.png -------------------------------------------------------------------------------- /img/ch06/akg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/akg.png -------------------------------------------------------------------------------- /img/ch06/akg_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/akg_cn.png -------------------------------------------------------------------------------- /img/ch06/compute_unit_cn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch06/compute_unit_cn.png -------------------------------------------------------------------------------- /img/ch07/7.1/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.1/pipeline.png -------------------------------------------------------------------------------- /img/ch07/7.2/RDD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/RDD.png -------------------------------------------------------------------------------- /img/ch07/7.2/dataset-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/dataset-plugin.png -------------------------------------------------------------------------------- /img/ch07/7.2/dataset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/dataset.png -------------------------------------------------------------------------------- /img/ch07/7.2/dataset_table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/dataset_table.png -------------------------------------------------------------------------------- /img/ch07/7.2/image_process_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/image_process_pipeline.png -------------------------------------------------------------------------------- /img/ch07/7.2/operation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.2/operation.png -------------------------------------------------------------------------------- /img/ch07/7.3/MindRecord_format.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/MindRecord_format.png -------------------------------------------------------------------------------- /img/ch07/7.3/async_data_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/async_data_process.png -------------------------------------------------------------------------------- /img/ch07/7.3/file_indexing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/file_indexing.png -------------------------------------------------------------------------------- /img/ch07/7.3/map_reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/map_reduce.png -------------------------------------------------------------------------------- /img/ch07/7.3/operator_parallisim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/operator_parallisim.png -------------------------------------------------------------------------------- /img/ch07/7.3/partition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/partition.png -------------------------------------------------------------------------------- /img/ch07/7.3/pipeline_parallisim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/pipeline_parallisim.png -------------------------------------------------------------------------------- /img/ch07/7.3/pytorch_dataloader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/pytorch_dataloader.png -------------------------------------------------------------------------------- /img/ch07/7.3/single_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/single_pipeline.png -------------------------------------------------------------------------------- /img/ch07/7.3/uni_record.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.3/uni_record.png -------------------------------------------------------------------------------- /img/ch07/7.4/data_ordering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.4/data_ordering.png -------------------------------------------------------------------------------- /img/ch07/7.4/mindspore_data_order.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.4/mindspore_data_order.jpeg -------------------------------------------------------------------------------- /img/ch07/7.5/dali_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.5/dali_overview.png -------------------------------------------------------------------------------- /img/ch07/7.5/distribute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch07/7.5/distribute.png -------------------------------------------------------------------------------- /img/ch08/AttentionTS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/AttentionTS.png -------------------------------------------------------------------------------- /img/ch08/bn-replace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/bn-replace.png -------------------------------------------------------------------------------- /img/ch08/conv-bn-fusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/conv-bn-fusion.png -------------------------------------------------------------------------------- /img/ch08/conv_2d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/conv_2d.png -------------------------------------------------------------------------------- /img/ch08/conv_nhwc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/conv_nhwc.png -------------------------------------------------------------------------------- /img/ch08/crop-reorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/crop-reorder.png -------------------------------------------------------------------------------- /img/ch08/deepcomp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/deepcomp.png -------------------------------------------------------------------------------- /img/ch08/distillation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/distillation.png -------------------------------------------------------------------------------- /img/ch08/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/flow.png -------------------------------------------------------------------------------- /img/ch08/fmla.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/fmla.png -------------------------------------------------------------------------------- /img/ch08/gemm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/gemm.png -------------------------------------------------------------------------------- /img/ch08/img2col_input.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/img2col_input.png -------------------------------------------------------------------------------- /img/ch08/img2col_weight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/img2col_weight.png -------------------------------------------------------------------------------- /img/ch08/model_obfuscate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/model_obfuscate.png -------------------------------------------------------------------------------- /img/ch08/parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/parallel.png -------------------------------------------------------------------------------- /img/ch08/quant-minmax-outpoints.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/quant-minmax-outpoints.png -------------------------------------------------------------------------------- /img/ch08/quant-minmax.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/quant-minmax.png -------------------------------------------------------------------------------- /img/ch08/register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/register.png -------------------------------------------------------------------------------- /img/ch08/storage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/storage.png -------------------------------------------------------------------------------- /img/ch08/winograd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch08/winograd.png -------------------------------------------------------------------------------- /img/ch09/ch10-allreduce-process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-allreduce-process.png -------------------------------------------------------------------------------- /img/ch09/ch10-allreduce-state.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-allreduce-state.png -------------------------------------------------------------------------------- /img/ch09/ch10-collective-operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-collective-operators.png -------------------------------------------------------------------------------- /img/ch09/ch10-computation-increase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-computation-increase.png -------------------------------------------------------------------------------- /img/ch09/ch10-data-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-data-parallel.png -------------------------------------------------------------------------------- /img/ch09/ch10-datacentre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-datacentre.png -------------------------------------------------------------------------------- /img/ch09/ch10-hybrid-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-hybrid-parallel.png -------------------------------------------------------------------------------- /img/ch09/ch10-model-parallel-inter-op.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-model-parallel-inter-op.png -------------------------------------------------------------------------------- /img/ch09/ch10-model-parallel-intra-op.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-model-parallel-intra-op.png -------------------------------------------------------------------------------- /img/ch09/ch10-parameter-servers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-parameter-servers.png -------------------------------------------------------------------------------- /img/ch09/ch10-pipeline-parallel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-pipeline-parallel.png -------------------------------------------------------------------------------- /img/ch09/ch10-redistribution.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-redistribution.pdf -------------------------------------------------------------------------------- /img/ch09/ch10-redistribution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-redistribution.png -------------------------------------------------------------------------------- /img/ch09/ch10-single-node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-single-node.png -------------------------------------------------------------------------------- /img/ch09/ch10-single-vs-multi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch09/ch10-single-vs-multi.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/ch10-recommendation-models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/ch10-recommendation-models.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/ch10-recommendation-systems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/ch10-recommendation-systems.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/chain_replication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/chain_replication.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/content_embedding_missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/content_embedding_missing.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/dlrm_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/dlrm_model.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/ekko_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/ekko_overview.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/feature_store.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/feature_store.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/interaction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/interaction.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/offline_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/offline_update.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/online_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/online_update.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/p2p_replication.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/p2p_replication.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/parameter_server_in_recommendation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/parameter_server_in_recommendation.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/recommender_pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/recommender_pipeline.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/state_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/state_manager.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/system_challenges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/system_challenges.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/two_tower_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/two_tower_model.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/update_scheduler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/update_scheduler.png -------------------------------------------------------------------------------- /img/ch10/ch-recsys/user_embedding_missing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch-recsys/user_embedding_missing.png -------------------------------------------------------------------------------- /img/ch10/ch10-abstract-recommendation-systems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-abstract-recommendation-systems.png -------------------------------------------------------------------------------- /img/ch10/ch10-federated-learning-different-connection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-federated-learning-different-connection.png -------------------------------------------------------------------------------- /img/ch10/ch10-federated-learning-fedavg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-federated-learning-fedavg.png -------------------------------------------------------------------------------- /img/ch10/ch10-federated-learning-flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-federated-learning-flow.png -------------------------------------------------------------------------------- /img/ch10/ch10-federated-learning-signds.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-federated-learning-signds.PNG -------------------------------------------------------------------------------- /img/ch10/ch10-federated-learning-vfl-data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-federated-learning-vfl-data.png -------------------------------------------------------------------------------- /img/ch10/ch10-recommendation-models.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-recommendation-models.png -------------------------------------------------------------------------------- /img/ch10/ch10-recommendation-systems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch10/ch10-recommendation-systems.png -------------------------------------------------------------------------------- /img/ch11/XAI_methods.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/XAI_methods.PNG -------------------------------------------------------------------------------- /img/ch11/correct_correct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/correct_correct.png -------------------------------------------------------------------------------- /img/ch11/correct_wrong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/correct_wrong.png -------------------------------------------------------------------------------- /img/ch11/mindspore_xai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/mindspore_xai.png -------------------------------------------------------------------------------- /img/ch11/tabular.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/tabular.png -------------------------------------------------------------------------------- /img/ch11/tabular_shap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/tabular_shap.png -------------------------------------------------------------------------------- /img/ch11/tb_net.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/tb_net.png -------------------------------------------------------------------------------- /img/ch11/tbnet_finance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/tbnet_finance.png -------------------------------------------------------------------------------- /img/ch11/wrong_wrong.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/wrong_wrong.png -------------------------------------------------------------------------------- /img/ch11/xai_concept.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_concept.png -------------------------------------------------------------------------------- /img/ch11/xai_concept_en.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_concept_en.PNG -------------------------------------------------------------------------------- /img/ch11/xai_data_driven.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_data_driven.png -------------------------------------------------------------------------------- /img/ch11/xai_global_feature_importance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_global_feature_importance.png -------------------------------------------------------------------------------- /img/ch11/xai_gradient_based.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_gradient_based.PNG -------------------------------------------------------------------------------- /img/ch11/xai_kg_recommendation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_kg_recommendation.png -------------------------------------------------------------------------------- /img/ch11/xai_lime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_lime.png -------------------------------------------------------------------------------- /img/ch11/xai_tcav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch11/xai_tcav.png -------------------------------------------------------------------------------- /img/ch12/ch12-a3c.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-a3c.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-a3c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-a3c.png -------------------------------------------------------------------------------- /img/ch12/ch12-impala.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-impala.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-impala.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-impala.png -------------------------------------------------------------------------------- /img/ch12/ch12-marl-fsp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-fsp.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-marl-fsp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-fsp.png -------------------------------------------------------------------------------- /img/ch12/ch12-marl-sp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-sp.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-marl-sp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-sp.png -------------------------------------------------------------------------------- /img/ch12/ch12-marl-sys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-sys.png -------------------------------------------------------------------------------- /img/ch12/ch12-marl-train.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-train.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-marl-train.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl-train.png -------------------------------------------------------------------------------- /img/ch12/ch12-marl.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-marl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-marl.png -------------------------------------------------------------------------------- /img/ch12/ch12-rl.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rl.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-rl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rl.png -------------------------------------------------------------------------------- /img/ch12/ch12-rllib-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rllib-arch.png -------------------------------------------------------------------------------- /img/ch12/ch12-rllib-distributed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rllib-distributed.png -------------------------------------------------------------------------------- /img/ch12/ch12-rlzoo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rlzoo.pdf -------------------------------------------------------------------------------- /img/ch12/ch12-rlzoo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch12/ch12-rlzoo.png -------------------------------------------------------------------------------- /img/ch13/ROS2_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ROS2_arch.png -------------------------------------------------------------------------------- /img/ch13/affordance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/affordance.png -------------------------------------------------------------------------------- /img/ch13/idm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/idm.png -------------------------------------------------------------------------------- /img/ch13/orbslam3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/orbslam3.png -------------------------------------------------------------------------------- /img/ch13/real-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/real-world.png -------------------------------------------------------------------------------- /img/ch13/rl_ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/rl_ad.png -------------------------------------------------------------------------------- /img/ch13/robot_learning_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/robot_learning_overview.png -------------------------------------------------------------------------------- /img/ch13/ros-apple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros-apple.jpg -------------------------------------------------------------------------------- /img/ch13/ros-pineapple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros-pineapple.jpg -------------------------------------------------------------------------------- /img/ch13/ros2-gazebo-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2-gazebo-1.JPG -------------------------------------------------------------------------------- /img/ch13/ros2-rviz-1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2-rviz-1.JPG -------------------------------------------------------------------------------- /img/ch13/ros2-rviz-2.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2-rviz-2.JPG -------------------------------------------------------------------------------- /img/ch13/ros2_actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2_actions.png -------------------------------------------------------------------------------- /img/ch13/ros2_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2_graph.png -------------------------------------------------------------------------------- /img/ch13/ros2_services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2_services.png -------------------------------------------------------------------------------- /img/ch13/ros2_topics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/ros2_topics.png -------------------------------------------------------------------------------- /img/ch13/safe_learning_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/safe_learning_control.png -------------------------------------------------------------------------------- /img/ch13/simulator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/simulator.png -------------------------------------------------------------------------------- /img/ch13/vehicle_computing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch13/vehicle_computing.png -------------------------------------------------------------------------------- /img/ch_basic/conv_computation_v4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/conv_computation_v4.png -------------------------------------------------------------------------------- /img/ch_basic/gradient_descent2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/gradient_descent2.png -------------------------------------------------------------------------------- /img/ch_basic/mlp2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/mlp2.png -------------------------------------------------------------------------------- /img/ch_basic/pooling_v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/pooling_v3.png -------------------------------------------------------------------------------- /img/ch_basic/rnn_simple_cell2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/rnn_simple_cell2.png -------------------------------------------------------------------------------- /img/ch_basic/single_neuron2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/single_neuron2.png -------------------------------------------------------------------------------- /img/ch_basic/single_neuron_bias2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/single_neuron_bias2.png -------------------------------------------------------------------------------- /img/ch_basic/single_neuron_decision_boundary2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/single_neuron_decision_boundary2.png -------------------------------------------------------------------------------- /img/ch_basic/two_neurons2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/ch_basic/two_neurons2.png -------------------------------------------------------------------------------- /img/guide/step1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step1.png -------------------------------------------------------------------------------- /img/guide/step2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step2.png -------------------------------------------------------------------------------- /img/guide/step3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step3.png -------------------------------------------------------------------------------- /img/guide/step4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step4.png -------------------------------------------------------------------------------- /img/guide/step5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step5.png -------------------------------------------------------------------------------- /img/guide/step6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/img/guide/step6.png -------------------------------------------------------------------------------- /index.md: -------------------------------------------------------------------------------- 1 | 机器学习系统:设计和实现 2 | ========================= 3 | 4 | ```eval_rst 5 | .. raw:: html 6 | :file: frontpage.html 7 | ``` 8 | 9 | ```toc 10 | :maxdepth: 2 11 | :numbered: 12 | 13 | chapter_preface/index 14 | chapter_introduction/index 15 | chapter_programming_interface/index 16 | chapter_computational_graph/index 17 | 18 | chapter_preface_advanced/index 19 | 20 | chapter_frontend_and_ir/index 21 | chapter_backend_and_runtime/index 22 | chapter_accelerator/index 23 | chapter_data_processing/index 24 | chapter_model_deployment/index 25 | chapter_distributed_training/index 26 | 27 | chapter_preface_extension/index 28 | 29 | chapter_recommender_system/index 30 | chapter_federated_learning/index 31 | chapter_reinforcement_learning/index 32 | chapter_explainable_AI/index 33 | chapter_rl_sys/index 34 | 35 | ``` 36 | 37 | ```toc 38 | :maxdepth: 1 39 | 40 | appendix_machine_learning_introduction/index 41 | ``` 42 | -------------------------------------------------------------------------------- /info/Pic-Instruction/Pic_Templates_and_Samples.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/info/Pic-Instruction/Pic_Templates_and_Samples.pptx -------------------------------------------------------------------------------- /info/Pic-Instruction/Requirements and Instructions.md: -------------------------------------------------------------------------------- 1 | ## 书籍图片制作模板 2 | 为了保证图书中图片尽量统一,我们输出了图形的基础模板,包括色系、线条、箭头、框图等流程图常用的模块。 3 | 大家可以根据自己绘制流程图的需求,选择合适的组件进行绘制。为了方便大家作图,我们以PPT的形式提供给大家,不需要开发者掌握单独的作图工具。 4 | 使用的简单流程如下: 5 | 1、梳理流程图的逻辑。 6 | 2、使用PPT中的模板进行绘制。 7 | 3、通过PPT导出图片,建议为png格式。 8 | 4、将导出后的图片放到相应img目录相应的章节,在文档中进行引用。 9 | 10 | 字体说明: 11 | 1、正文采用五号字体(中文为宋体,英文为 Time New Roman)。 12 | 2、插图/插表的标题用小五号黑体,插图/插表的其他文字用小五号字体(中文为宋体,英文为 Time New Roman)。 13 | 3、代码采用小五号, Courier New字体。 14 | 15 | 16 | -------------------------------------------------------------------------------- /info/editors.md: -------------------------------------------------------------------------------- 1 | # 编辑和作者 2 | 3 | ## 章节编辑 4 | 5 | 本书由超过30位人工智能系统领域的学术专家和开发人员共同完成。以下为各个章节编辑: 6 | 7 | 项目README: [@luomai](https://github.com/luomai) 8 | 9 | 序言:[@luomai](https://github.com/luomai) 10 | 11 | 导论:[@luomai](https://github.com/luomai) 12 | 13 | 编程接口:[@Laicheng0830](https://github.com/Laicheng0830) 14 | 15 | 计算图:[@hanjr92](https://github.com/hanjr92) 16 | 17 | 进阶篇序言:[@ganzhiliang](https://github.com/ganzhiliang) 18 | 19 | 编译器前端和IR: [@LiangZhibo](https://github.com/LiangZhibo) 20 | 21 | 编译器后端和运行时: [@chujinjin101](https://github.com/chujinjin101) 22 | 23 | 硬件加速器:[@anyrenwei](https://github.com/anyrenwei) 24 | 25 | 数据处理框架: [@eedalong](https://github.com/eedalong) 26 | 27 | 模型部署: [@AssassinG](https://github.com/AssassinGQ) 28 | 29 | 分布式训练系统: [@luomai](https://github.com/luomai) 30 | 31 | 拓展篇序言:[@luomai](https://github.com/luomai) 32 | 33 | 深度学习推荐系统:[@future-xy](https://github.com/future-xy) 34 | 35 | 联邦学习系统:[@chengtianwu](https://github.com/chengtianwu) 36 | 37 | 强化学习系统:[@quantumiracle](https://github.com/quantumiracle) 38 | 39 | 可解释性AI系统:[@HaoyangLee](https://github.com/HaoyangLee) 40 | 41 | 机器人系统:[@Jack](https://github.com/Jiankai-Sun) 42 | 43 | 附录:机器学习介绍:[@Hao](https://github.com/zsdonghao) 44 | 45 | ## 加入我们 46 | 47 | 我们创建了OpenMLSys微信群来讨论书籍的写作和拓展。如果希望加入我们,可以扫以下二维码(加的时候请介绍自己,并说明希望参与书籍的哪方面工作): 48 | 49 | ![OpenMLSys社区微信群](./mlsys_group.png) 50 | -------------------------------------------------------------------------------- /info/info.md: -------------------------------------------------------------------------------- 1 | ## 环境安装 2 | 机器学习系统书籍部署在GitHub是依赖于d2lbook工具实现的。因此我们首先要安装d2lbook。 3 | ```bash 4 | git clone https://github.com/openmlsys/d2l-book.git 5 | cd d2l-book 6 | python setup.py install 7 | ``` 8 | 使用d2lbook构建HTML需要安装`pandoc`, 可以使用`conda install pandoc` (如果是MacOS可以用Homebrew), apt源中pandoc发布版本较低,表格转换格式可能有误,请尽量使用较新版本的pandoc。 9 | 构建PDF时如果有SVG图片需要安装LibRsvg来转换SVG图片,安装`librsvg`可以通过`apt-get install librsvg`(如果是MacOS可以用Homebrew)。 10 | 当然构建PDF必须要有LaTeX,如安装[Tex Live](https://www.tug.org/texlive/). 11 | 12 | ## 编译HTML版本 13 | 在编译前先下载[openmlsys-zh](https://github.com/openmlsys/openmlsys-zh) , 所有的编译命令都在这个文件目录内执行。 14 | ```bash 15 | git clone https://github.com/openmlsys/openmlsys-zh.git 16 | cd openmlsys-zh 17 | ``` 18 | 使用d2lbook工具编译HTML。 请尽量使用build_html.sh脚本进行编译,保证首页正确合并到书籍中去。 19 | ``` 20 | sh build_html.sh 21 | ``` 22 | 23 | 生成的html会在`_build/html`。 24 | 25 | 此时我们将编译好的html整个文件夹下的内容拷贝至openmlsys.github.io的docs发布。 26 | 27 | 需要注意的是docs目录下的.nojekyll不要删除了,不然网页会没有渲染。 28 | 29 | ## 样式规范 30 | 31 | 贡献请遵照本教程的[样式规范](style.md)。 32 | 33 | ## 中英文术语对照 34 | 35 | 翻译请参照[中英文术语对照](terminology.md)。 36 | -------------------------------------------------------------------------------- /info/issue.md: -------------------------------------------------------------------------------- 1 | # Issue的label 2 | 目前我们的issue主要有如下label: 3 | 4 | - great suggestion: 表示该issue是用户为本书的内容提供的写作建议,并且该建议是一个很好的建立 5 | - discussion: 表示该issue是用户针对文章内容进行特定讨论,或用户对内容进行了建议并且该建议还处在商讨中 6 | - to be confirmed: 表示该issue被assign给了章节作者,但是目前章节作者并没有回复处理这个issue 7 | - confirmed: 表示该issue被章节作者已经确认 8 | - fixed: 表示该issue相关的pr被approve/merge 9 | 10 | 常规而言,一个针对书籍内容校正的issue的状态变换应该为: 11 | 12 | to be confirmed ----> confirmed ----> fixed 13 | -------------------------------------------------------------------------------- /info/mlsys_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/info/mlsys_group.png -------------------------------------------------------------------------------- /info/refenence_guide.md: -------------------------------------------------------------------------------- 1 | # 参考文献引用方式 2 | 下面为参考文献的引用,需要注意引用时前面需要有一个空格: 3 | 1. 单篇参考文献 4 | 这篇文章参考了论文 :cite:`cnn2015` 5 | 2. 多篇参考文献可以用逗号分开 6 | 这篇文章参考了论文 :cite:`cnn2015,rnn2015` 7 | 3. 此时在对应bib中应该有如下参考文献 8 | @inproceedings{cnn2015, 9 | title = {CNN}, 10 | author = {xxx}, 11 | year = {2015}, 12 | keywords = {xxx} 13 | } 14 | @inproceedings{rnn2015, 15 | title = {RNN}, 16 | author = {xxx}, 17 | year = {2015}, 18 | keywords = {xxx} 19 | } 20 | 21 | # 参考文献置于章节末尾方式 22 | 1.将章节所引用的全部参考文献生成一个chapter.pip,放置于references文件夹下。 23 | 如机器人系统章节将该章节参考文献全部放在rlsys.bib,并将其放在reference文件夹下。 24 | 25 | ``` 26 | 参考文献目录 27 | 28 | /references/rlsys.bib` 29 | ``` 30 | 2.将对应章节参考文献引用添加至文章末尾处,如机器人系统章节在summary最后加上 31 | ``` 32 | ## 参考文献 33 | 34 | :bibliography:`../references/rlsys.bib` 35 | ``` 36 | -------------------------------------------------------------------------------- /info/style.md: -------------------------------------------------------------------------------- 1 | # 样式规范 2 | 从LaTeX迁移到Markdown。工具列表: 3 | * [Pandoc:](https://pandoc.org/getting-started.html) LaTeX转换为Markdown。 4 | * [Inkscape:](https://inkscape.org/release/inkscape-1.1.1/) pdf图片文件转换成svg图片文件 5 | 6 | 书写内容: 7 | * 页面划分:每章建一个目录,以一级子章节的维度建一个md页面,[参考地址](https://github.com/openmlsys/openmlsys-zh/tree/master/chapter_programming_interface) 。 8 | * 图存放位置: openmlsys-zh/img/自己章节,如openmlsys-zh/img/ch01,把自己章节的图片全部放置在对应目录。 9 | 10 | ## 文本 11 | 12 | * LaTeX文件转换Markdown文件 13 | * Linux下安装Pandoc命令:apt-get install pandoc 14 | * 使用Pandoc命令:pandoc -s example.tex -o example.md 15 | * 使用Pandoc转换后需要注意修改的地方 16 | * 表格需要手动改 17 | * 图片需要手动改 18 | * 公式部分可能会有不正确,需要注意 19 | * 代码部分需要手动改,样式如下: 20 | ```markdown 21 | ``` python 22 | import os 23 | import argparse 24 | ``` 25 | ``` 26 | * 转换得到的md中,如果使用了"-"语法,则不能出现以下形式的内容: 27 | ```markdown 28 | - title 29 | 30 | content content content content content con... 31 | ``` 32 | 即"-"之后空了一行,且内容行首空了4格,否则d2lbook会编译失败: 33 | 34 | ## 图片 35 | 36 | * 软件 37 | * 使用PPT制图,以pdf导出,再使用Inkscape转成svg。 38 | * Inkscape软件使用: 39 | * 用Inkscape打开pdf,渐变曲线精细度选择为精细。 40 | ![Inkscape打开PDF](../img/guide/step1.png) 41 | * 选中图片,我们可以看到图和其白底 42 | ![1](../img/guide/step2.png) 43 | * 随意找一块能选择的图,此时会出现周边有虚框 44 | ![2](../img/guide/step3.png) 45 | * 按住ctrl拉一下白色框,此时能将图片和白框分离出来,按Delete删除白框。 46 | ![3](../img/guide/step4.png) 47 | * 选择文件-文档属性-缩放页面内容-缩放页面到绘图或选区。 48 | ![4](../img/guide/step5.png) 49 | * 最后保存图片,用Pycharm看图片效果如下:无白色底,大小刚好框住整图。 50 | ![5](../img/guide/step6.png) 51 | 52 | * 样式 53 | * 格式: 54 | * svg:自己绘制的图片需要用svg,注意去掉白底 55 | * png:一些常规举例图片不需去除白底的可以使用png 56 | * md里插入图片,大小选择宽度800个像素(可以依据自己生成的网页效果调整大小),label自动生成,例如: 57 | ```python 58 | ![机器学习系统工作流](../img/ch02/workflow.svg) 59 | :width:`800px` 60 | :label:`img_workflow` 61 | ``` 62 | 63 | * 版权 64 | * 不使用网络图片 65 | * 位置 66 | * 两张图不可以较邻近 67 | * 两张图拼一下 68 | * 引用 69 | * 图片引用如下 70 | ```python 71 | ![机器学习系统工作流](../img/ch02/workflow.svg) 72 | :width:`800px` 73 | :label:`img_workflow` 74 | 我们给这个图片打了标签img_workflow,此时对其进行引用如下 75 | 机器学习系统工作流如 :numref:`img_workflow` 。必须注意的是在引用时冒号前要空有一个字符距离。 76 | ``` 77 | * 表格引用和图片引用类似,流程依旧是打上标签,然后用 :numref:‘引用的标签’ 78 | ```python 79 | 下面为表格引用方式: 80 | 81 | | Year | Number | Comment | 82 | | --- | --- | --- | 83 | | 2018 | 100 | Good year | 84 | :label:`table` 85 | 表格引用使用 :numref:`table` 86 | ``` 87 | * 公式引用依旧也是打上标签,然后使用 :eqref:`‘引用的标签’ 88 | ```python 89 | 下面为公式引用方式: 90 | 91 | $$\hat{\mathbf{y}}=\mathbf X \mathbf{w}+b$$ 92 | :eqlabel:`linear` 93 | 公式引用使用 :eqref:`linear` 94 | ``` 95 | * 参考文献引用方式,参考文献放在references/xxx.bib,如需新增,只需在该文件中添加即可。参考文献使用 :cite:`文献` 96 | 需要注意的是bib里的参考文献不能有重复的。 97 | ```python 98 | 下面参考文献的引用: 99 | 1. 单篇参考文献 100 | 这篇文章参考了论文 :cite:`cnn2015` 101 | 2. 多篇参考文献可以用逗号分开 102 | 这篇文章参考了论文 :cite:`cnn2015,rnn2015` 103 | 104 | 此时在对应bib中应该有如下参考文献 105 | @inproceedings{cnn2015, 106 | title = {CNN}, 107 | author = {xxx}, 108 | year = {2015}, 109 | keywords = {xxx} 110 | } 111 | @inproceedings{rnn2015, 112 | title = {RNN}, 113 | author = {xxx}, 114 | year = {2015}, 115 | keywords = {xxx} 116 | } 117 | ``` 118 | * 章节引用方式我们可以在节标题后放置一个标签,以允许该节的标签引用它。标签格式是:label:`标签名` 119 | ```python 120 | ### Referencing Sections 121 | :label:`my_sec3` 122 | ``` 123 | 然后,我们可以在代码块中通过:ref:`标签名`引用这一节 124 | ```python 125 | :ref:`my_sec3` 显示了章节引用. 126 | ``` 127 | 128 | * 其他转换方式 129 | * 如果图中有很多公式,使用工具导入可能会有大量公式乱码,此时可以将图保存为.png格式。 130 | * 使用[在线图片去底工具](https://www.aigei.com/bgremover/) 将图片中的白底去除。 131 | 132 | 133 | 134 | 135 | -------------------------------------------------------------------------------- /info/terminology.md: -------------------------------------------------------------------------------- 1 | ## 英汉术语对照 2 | 3 | 鞍点,saddle point 4 | 5 | 变换,transform 6 | 7 | 编码器,encoder 8 | 9 | 标签,label 10 | 11 | 步幅,stride 12 | 13 | 参数,parameter 14 | 15 | 长短期记忆网络,long short-term memory (LSTM) 16 | 17 | 超参数,hyperparameter 18 | 19 | 层序softmax,hierarchical softmax 20 | 21 | 查准率,precision 22 | 23 | 成本,cost 24 | 25 | 词表,vocabulary 26 | 27 | 词嵌入,word embedding 28 | 29 | 词向量,word vector 30 | 31 | 词元,token 32 | 33 | 词元分析器,tokenizer 34 | 35 | 词元化,tokenize 36 | 37 | 汇聚层,pooling layer 38 | 39 | 稠密,dense 40 | 41 | 大小,size 42 | 43 | 导入,import 44 | 45 | 轮,epoch 46 | 47 | 暂退法,dropout 48 | 49 | 动量法,momentum (method) 50 | 51 | 独立同分布,independent and identically distributed (i.i.d.) 52 | 53 | 端到端,end-to-end 54 | 55 | 多层感知机,multilayer perceptron 56 | 57 | 多头注意力,multi-head attention 58 | 59 | 二元分类,binary classification 60 | 61 | 二元,bigram 62 | 63 | 子采样,subsample 64 | 65 | 发散,diverge 66 | 67 | 泛化,generalization 68 | 69 | 泛化误差,generalization error 70 | 71 | 方差,variance 72 | 73 | 分类,classification 74 | 75 | 分类器,classifier 76 | 77 | 负采样,negative sampling 78 | 79 | 感受野,receptive field 80 | 81 | 格拉姆矩阵,Gram matrix 82 | 83 | 共现,co-occurrence 84 | 85 | 广播,broadcast 86 | 87 | 规范化,normalization 88 | 89 | 过拟合,overfitting 90 | 91 | 核回归,kernel regression 92 | 93 | 恒等映射,identity mapping 94 | 95 | 假设,hypothesis 96 | 97 | 基准,baseline 98 | 99 | 激活函数,activation function 100 | 101 | 解码器,decoder 102 | 103 | 近似法,approximate method 104 | 105 | 经验风险最小化,empirical risk minimization 106 | 107 | 局部最小值,local minimum 108 | 109 | 卷积核,convolutional kernel 110 | 111 | 卷积神经网络,convolutional neural network 112 | 113 | 决策边界,decision boundary 114 | 115 | 均值,mean 116 | 117 | 均方误差,mean squared error 118 | 119 | 均匀采样,uniform sampling 120 | 121 | 块,block 122 | 123 | 困惑度,perplexity 124 | 125 | 拉普拉斯平滑,Laplace smoothing 126 | 127 | 连结,concatenate 128 | 129 | 类,class 130 | 131 | 交叉熵,cross-entropy 132 | 133 | 连续词袋,continous bag-of-words (CBOW) 134 | 135 | 零张量,zero tensor 136 | 137 | 流水线,pipeline 138 | 139 | 滤波器,filter 140 | 141 | 门控循环单元,gated recurrent units (GRU) 142 | 143 | 目标检测,object detection 144 | 145 | 偏置,bias 146 | 147 | 偏导数,partial derivative 148 | 149 | 偏移量,offset 150 | 151 | 批量,batch 152 | 153 | 齐普夫定律,Zipf's law 154 | 155 | 欠拟合,underfitting 156 | 157 | 情感分析,sentiment analysis 158 | 159 | 全连接层,fully-connected layer 160 | 161 | 权重,weight 162 | 163 | 三元,trigram 164 | 165 | 上采样,upsample 166 | 167 | 上下文变量,context variable 168 | 169 | 上下文窗口,context window 170 | 171 | 上下文词,context word 172 | 173 | 上下文向量,context vector 174 | 175 | 实例/示例,instance 176 | 177 | 收敛,converge 178 | 179 | 属性,property 180 | 181 | 数值方法,numerical method 182 | 183 | 数据集,dataset 184 | 185 | 数据示例,data instance 186 | 187 | 数据样例,data example 188 | 189 | 顺序分区,sequential partitioning 190 | 191 | softmax回归,softmax regression 192 | 193 | 随机采样,random sampling 194 | 195 | 损失函数,loss function 196 | 197 | 双向循环神经网络,bidirectional recurrent neural network 198 | 199 | 特征,feature 200 | 201 | 特征图,feature map 202 | 203 | 特征值,eigenvalue 204 | 205 | 梯度,gradient 206 | 207 | 梯度裁剪,gradient clipping 208 | 209 | 梯度消失,vanishing gradients 210 | 211 | 填充,padding 212 | 213 | 跳元模型,skip-gram model 214 | 215 | 调参,tune hyperparameter 216 | 217 | 停用词,stop words 218 | 219 | 通道,channel 220 | 221 | 凸优化,convex optimization 222 | 223 | 图像,image 224 | 225 | 未知词元,unknown token 226 | 227 | 无偏估计,unbiased estimate 228 | 229 | 误差,error 230 | 231 | 小批量,minibatch 232 | 233 | 小批量梯度,minibatch gradient 234 | 235 | 线性模型,linear model 236 | 237 | 线性回归,linear regression 238 | 239 | 协同过滤,collaborative filtering 240 | 241 | 学习率,learning rate 242 | 243 | 训练误差,training error 244 | 245 | 循环神经网络,recurrent neural network (RNN) 246 | 247 | 样例,example 248 | 249 | 一维梯度下降,gradient descent in one-dimensional space 250 | 251 | 一元,unigram 252 | 253 | 隐藏变量,hidden variable 254 | 255 | 隐藏层,hidden layer 256 | 257 | 优化器,optimizer 258 | 259 | 语料库,corpus 260 | 261 | 运算符,operator 262 | 263 | 自注意力,self-attention 264 | 265 | 真实值,ground truth 266 | 267 | 指标,metric 268 | 269 | 支持向量机,support vector machine 270 | 271 | 注意力机制,attention mechanism 272 | 273 | 注意力模型,attention model 274 | 275 | 注意力提示,attention cue 276 | 277 | 准确率/精度,accuracy 278 | -------------------------------------------------------------------------------- /references/appendix.bib: -------------------------------------------------------------------------------- 1 | @article{rosenblatt1958perceptron, 2 | title={The perceptron: a probabilistic model for information storage and organization in the brain.}, 3 | author={Rosenblatt, Frank}, 4 | journal={Psychological Review}, 5 | volume={65}, 6 | number={6}, 7 | pages={386}, 8 | year={1958}, 9 | publisher={American Psychological Association} 10 | } 11 | 12 | @article{lecun1989backpropagation, 13 | title={Backpropagation applied to handwritten zip code recognition}, 14 | author={LeCun, Yann and Boser, Bernhard and Denker, John S and Henderson, Donnie and Howard, Richard E and Hubbard, Wayne and Jackel, Lawrence D}, 15 | journal={Neural computation}, 16 | volume={1}, 17 | number={4}, 18 | pages={541--551}, 19 | year={1989}, 20 | publisher={MIT Press} 21 | } 22 | 23 | @inproceedings{krizhevsky2012imagenet, 24 | title={Imagenet classification with deep convolutional neural networks}, 25 | author={Krizhevsky, Alex and Sutskever, Ilya and Hinton, Geoffrey E}, 26 | booktitle={Advances in Neural Information Processing Systems}, 27 | pages={1097--1105}, 28 | year={2012} 29 | } 30 | 31 | @inproceedings{he2016deep, 32 | title={{Deep Residual Learning for Image Recognition}}, 33 | author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian}, 34 | booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, 35 | year={2016} 36 | } 37 | 38 | @article{rumelhart1986learning, 39 | title={Learning representations by back-propagating errors}, 40 | author={Rumelhart, David E and Hinton, Geoffrey E and Williams, Ronald J}, 41 | journal={Nature}, 42 | volume={323}, 43 | number={6088}, 44 | pages={533}, 45 | year={1986}, 46 | publisher={Nature Publishing Group} 47 | } 48 | 49 | @article{Hochreiter1997lstm, 50 | author = {Hochreiter, Sepp and Hochreiter, S and Schmidhuber, J{\"{u}}rgen and Schmidhuber, J}, 51 | isbn = {08997667 (ISSN)}, 52 | issn = {0899-7667}, 53 | journal = {Neural Computation}, 54 | number = {8}, 55 | pages = {1735--80}, 56 | pmid = {9377276}, 57 | title = {{Long Short-Term Memory.}}, 58 | volume = {9}, 59 | year = {1997} 60 | } 61 | 62 | @inproceedings{vaswani2017attention, 63 | title={Attention is all you need}, 64 | author={Vaswani, Ashish and Shazeer, Noam and Parmar, Niki and Uszkoreit, Jakob and Jones, Llion and Gomez, Aidan N and Kaiser, {\L}ukasz and Polosukhin, Illia}, 65 | booktitle={Advances in Neural Information Processing Systems}, 66 | pages={5998--6008}, 67 | year={2017} 68 | } 69 | 70 | @article{lecun2015deep, 71 | title={Deep learning}, 72 | author={LeCun, Yann and Bengio, Yoshua and Hinton, Geoffrey}, 73 | journal={Nature}, 74 | volume={521}, 75 | number={7553}, 76 | pages={436}, 77 | year={2015}, 78 | publisher={Nature Publishing Group} 79 | } 80 | 81 | @inproceedings{KingmaAdam2014, 82 | title = {{Adam}: A Method for Stochastic Optimization}, 83 | author = {Kingma, Diederik and Ba, Jimmy}, 84 | booktitle = {Proceedings of the International Conference on Learning Representations (ICLR)}, 85 | year = {2014} 86 | } 87 | 88 | @techreport{tieleman2012rmsprop, 89 | title={Divide the gradient by a running average of its recent magnitude. COURSERA: Neural networks for machine learning}, 90 | author={Tieleman, T and Hinton, G}, 91 | year={2017}, 92 | institution={Technical Report} 93 | } 94 | 95 | @article{duchi2011adagrad, 96 | title={Adaptive subgradient methods for online learning and stochastic optimization}, 97 | author={Duchi, John and Hazan, Elad and Singer, Yoram}, 98 | journal={Journal of Machine Learning Research (JMLR)}, 99 | volume={12}, 100 | number={Jul}, 101 | pages={2121--2159}, 102 | year={2011} 103 | } -------------------------------------------------------------------------------- /references/backend.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/backend.bib -------------------------------------------------------------------------------- /references/data.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/data.bib -------------------------------------------------------------------------------- /references/extension.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/extension.bib -------------------------------------------------------------------------------- /references/graph.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/graph.bib -------------------------------------------------------------------------------- /references/interface.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/interface.bib -------------------------------------------------------------------------------- /references/introduction.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/introduction.bib -------------------------------------------------------------------------------- /references/model.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/model.bib -------------------------------------------------------------------------------- /references/model_deployment.bib: -------------------------------------------------------------------------------- 1 | @article{attentionTS, 2 | title={Paying more attention to attention: Improving the performance of convolutional neural networks via attention transfer}, 3 | author={Zagoruyko, Sergey and Komodakis, Nikos}, 4 | journal={arXiv preprint arXiv:1612.03928}, 5 | year={2016} 6 | } 7 | 8 | @inproceedings{bagherinezhad2017lcnn, 9 | title={Lcnn: Lookup-based convolutional neural network}, 10 | author={Bagherinezhad, Hessam and Rastegari, Mohammad and Farhadi, Ali}, 11 | booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition}, 12 | pages={7120--7129}, 13 | year={2017} 14 | } 15 | 16 | @article{Distill, 17 | title={Distilling the knowledge in a neural network}, 18 | author={Hinton, Geoffrey and Vinyals, Oriol and Dean, Jeff}, 19 | journal={arXiv preprint arXiv:1503.02531}, 20 | year={2015} 21 | } 22 | 23 | @article{han2015deep, 24 | title={Deep compression: Compressing deep neural networks with pruning, trained quantization and huffman coding}, 25 | author={Han, Song and Mao, Huizi and Dally, William J}, 26 | journal={arXiv preprint arXiv:1510.00149}, 27 | year={2015} 28 | } 29 | -------------------------------------------------------------------------------- /references/training.bib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/references/training.bib -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | bs4 2 | sphinx==4.4.0 3 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/favicon.png -------------------------------------------------------------------------------- /static/image/guozhijian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/guozhijian.png -------------------------------------------------------------------------------- /static/image/jinxuefeng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/jinxuefeng.png -------------------------------------------------------------------------------- /static/image/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/logo.png -------------------------------------------------------------------------------- /static/image/wanghanchen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/wanghanchen.png -------------------------------------------------------------------------------- /static/image/wutiancheng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/wutiancheng.png -------------------------------------------------------------------------------- /static/image/zhaizhiqiang.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/zhaizhiqiang.png -------------------------------------------------------------------------------- /static/image/zhangqinghua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/zhangqinghua.png -------------------------------------------------------------------------------- /static/image/zhangrenwei.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/image/zhangrenwei.png -------------------------------------------------------------------------------- /static/logo-with-text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/logo-with-text.png -------------------------------------------------------------------------------- /static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openmlsys/openmlsys-zh/1492ec6c41013046e0bcf9a2d2f5934c99062b47/static/logo.png -------------------------------------------------------------------------------- /static/readme.md: -------------------------------------------------------------------------------- 1 | ###Acknowledge 2 | 首页风格及源码参考自[动手学深度学习](https://github.com/d2l-ai/d2l-zh),特此提出感谢。 -------------------------------------------------------------------------------- /tools/contribution_analysis.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import csv 3 | 4 | def analysis_issue(): 5 | total_data = [] 6 | for page_num in range(20): 7 | print(f"Pulling page {page_num}") 8 | response = requests.get('https://api.github.com/repos/openmlsys/openmlsys-zh/issues', params={"state": "all", "per_page": 30, "page": page_num}) 9 | print(f"Result status: {response}") 10 | data = response.json() 11 | if len(data) == 0: 12 | break 13 | total_data += data 14 | 15 | all_issues = [] 16 | node_ids = set([]) 17 | for item in total_data: 18 | if isinstance(item, dict): 19 | if item["node_id"] not in node_ids: 20 | all_issues.append([item["user"]["login"], item["author_association"], 1, [item["url"].split("/")[-1]]]) 21 | node_ids.add(item["node_id"]) 22 | print(f"All issues and pr count {len(all_issues)}") 23 | total_count = {} 24 | for issue_item in all_issues: 25 | if total_count.get(issue_item[0], None) is None: 26 | total_count[issue_item[0]] = issue_item 27 | else: 28 | total_count[issue_item[0]][-2] += 1 29 | total_count[issue_item[0]][-1] += issue_item[-1] 30 | 31 | keys = sorted(total_count, key=lambda x: total_count[x][-2]) 32 | 33 | final_res = [] 34 | for key in keys: 35 | total_count[key][-1] = ",".join(total_count[key][-1]) 36 | final_res.append(total_count[key]) 37 | 38 | res_file = open("contribution_stats.csv", "w") 39 | csv_writer = csv.writer(res_file) 40 | csv_writer.writerow(["github id", "role", "issue and pr count", "issue or pr ids"]) 41 | csv_writer.writerows(final_res) 42 | analysis_issue() -------------------------------------------------------------------------------- /tools/format_tables.py: -------------------------------------------------------------------------------- 1 | from bs4 import BeautifulSoup 2 | import os 3 | 4 | """ 5 | 1. 本脚本文件会设置所有html文件,使得表格居中显示。 6 | 2. 确保你已经安装了bs4, 具体可以通过pip install bs4 进行安装 7 | """ 8 | 9 | root_path = "./" 10 | html_root_path = "_build/html/" 11 | 12 | 13 | def get_html_list(): 14 | index_html_path = os.path.join(root_path, html_root_path, "index.html") 15 | index_soup = BeautifulSoup(open(index_html_path)) 16 | 17 | content_list = index_soup.find(name="div", attrs={"class": "globaltoc"}). \ 18 | find_all(name="a", attrs={"class": "reference internal"}) 19 | html_list = [os.path.join(html_root_path, content_name["href"]) for content_name in content_list] 20 | return html_list 21 | 22 | 23 | def format_table(): 24 | html_list = get_html_list() 25 | for html_file in html_list: 26 | try: 27 | soup = BeautifulSoup(open(html_file)) 28 | all_tables = soup.find_all(name="table", attrs={"class": "docutils align-default"}) 29 | for table in all_tables: 30 | table["style"] = "margin-left:auto;margin-right:auto;margin-top:10px;margin-bottom:20px;" 31 | 32 | if len(all_tables): 33 | write_out_file = open(html_file, mode="w") 34 | write_out_file.write(soup.prettify()) 35 | write_out_file.close() 36 | except: 37 | pass 38 | 39 | 40 | if __name__ == "__main__": 41 | format_table() --------------------------------------------------------------------------------