From bf287a3ecd2325fdd168f47c660f886d75fc7ddb Mon Sep 17 00:00:00 2001 From: Chivier Humber Date: Mon, 26 Oct 2026 01:38:32 +0000 Subject: [PATCH] fix(v1-en): repair missing figures and section pages in English edition - Remap 129 broken image paths in v1/en_chapters to the files that exist under v1/img (old chapter numbering, renamed files, and .pdf figures that browsers cannot display inline). - Restore ch07/7.5/distribute.png and ch08/distillation.png, which were dropped in #499 because the `dist*` .gitignore rule matched them; narrow the rule to `/dist/`. - Fix the English toc blocks: chapter entries now point at real files and the root toc has part headings, so section pages are built again (previously only chapter index pages were generated). - Add tests/test_image_references.py to CI to catch missing or unrenderable figure references. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/main.yml | 1 + .github/workflows/update_docs.yml | 1 + .gitignore | 2 +- tests/test_image_references.py | 59 +++++++++ v1/en_chapters/SUMMARY.md | 124 +++++++++++++++--- .../accelerator_architecture.md | 10 +- .../accelerator_practise.md | 18 +-- v1/en_chapters/chapter_accelerator/index.md | 10 +- .../graph_optimizer.md | 8 +- .../chapter_backend_and_runtime/index.md | 14 +- .../kernel_selecter.md | 12 +- .../memory_allocator.md | 12 +- .../chapter_backend_and_runtime/overview.md | 2 +- .../background_and_functionality.md | 18 +-- .../components_of_computational_graph.md | 2 +- .../generation_of_computational_graph.md | 10 +- .../chapter_computational_graph/index.md | 11 +- .../schedule_of_computational_graph.md | 12 +- .../chapter_data_processing/program_model.md | 2 +- .../chapter_distributed_training/cluster.md | 2 +- .../collective.md | 4 +- .../chapter_distributed_training/index.md | 16 +-- .../chapter_distributed_training/methods.md | 10 +- .../chapter_distributed_training/overview.md | 4 +- .../parameter_servers.md | 2 +- v1/en_chapters/chapter_frontend_and_ir/ad.md | 6 +- .../ai_compiler_design_principle.md | 4 +- .../common_frontend_optimization_pass.md | 8 +- .../chapter_frontend_and_ir/index.md | 15 +-- .../intermediate_representation.md | 12 +- .../overview_of_frontend.md | 2 +- .../type_system_and_static_analysis.md | 2 +- .../chapter_introduction/architecture.md | 2 +- .../chapter_introduction/ecosystem.md | 2 +- v1/en_chapters/chapter_introduction/index.md | 16 +-- .../chapter_model_deployment/index.md | 14 +- .../model_compression.md | 4 +- .../model_converter_and_optimizer.md | 8 +- .../model_inference.md | 14 +- .../chapter_programming_interface/index.md | 12 +- .../ml_workflow.md | 2 +- .../neural_network_layer.md | 4 +- .../chapter_recommender_system/case_study.md | 6 +- .../chapter_recommender_system/index.md | 12 +- .../model_update.md | 2 +- .../multi_stage_recommender_system.md | 8 +- .../system_architecture.md | 8 +- .../chapter_reinforcement_learning/index.md | 12 +- .../chapter_reinforcement_learning/marl.md | 6 +- .../marl_sys.md | 4 +- .../rl_introduction.md | 2 +- .../single_node_rl.md | 2 +- v1/en_chapters/chapter_rl_sys/index.md | 10 +- v1/en_chapters/chapter_rl_sys/rl_sys_intro.md | 8 +- .../chapter_rl_sys/robot_learning.md | 6 +- v1/en_chapters/chapter_rl_sys/ros.md | 10 +- v1/en_chapters/index.md | 18 ++- v1/img/ch07/7.5/distribute.png | Bin 0 -> 74646 bytes v1/img/ch08/distillation.png | Bin 0 -> 30288 bytes 59 files changed, 372 insertions(+), 235 deletions(-) create mode 100644 tests/test_image_references.py create mode 100644 v1/img/ch07/7.5/distribute.png create mode 100644 v1/img/ch08/distillation.png diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 876b4a3..b4f22e8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -29,6 +29,7 @@ jobs: python3 -m unittest discover -s tests -p 'test_prepare_mdbook_zh.py' python3 -m unittest discover -s tests -p 'test_assemble_docs_publish_tree.py' python3 -m unittest discover -s tests -p 'test_ensure_book_resources.py' + python3 -m unittest discover -s tests -p 'test_image_references.py' python3 -m unittest discover -s tests -p 'test_update_docs_workflow.py' - name: Build v2 (EN + ZH) with mdBook diff --git a/.github/workflows/update_docs.yml b/.github/workflows/update_docs.yml index 5539bd6..4117746 100644 --- a/.github/workflows/update_docs.yml +++ b/.github/workflows/update_docs.yml @@ -28,6 +28,7 @@ jobs: python3 -m unittest discover -s tests -p 'test_prepare_mdbook_zh.py' python3 -m unittest discover -s tests -p 'test_assemble_docs_publish_tree.py' python3 -m unittest discover -s tests -p 'test_ensure_book_resources.py' + python3 -m unittest discover -s tests -p 'test_image_references.py' - name: Build v2 (EN + ZH) with mdBook run: bash build_mdbook_v2.sh diff --git a/.gitignore b/.gitignore index 585dc00..8083c76 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ data/ *.DS_Store *.csv *egg-info* -dist* +/dist/ _build/ test*.md run.sh diff --git a/tests/test_image_references.py b/tests/test_image_references.py new file mode 100644 index 0000000..b6c55b1 --- /dev/null +++ b/tests/test_image_references.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +import os +import re +import unittest +from pathlib import Path + +from tools.ensure_book_resources import RESOURCE_NAMES + +REPO_ROOT = Path(__file__).resolve().parent.parent +CHAPTER_DIRS = ( + REPO_ROOT / "v1" / "en_chapters", + REPO_ROOT / "v1" / "zh_chapters", +) +SHARED_RESOURCES = REPO_ROOT / "v1" +MARKDOWN_IMAGE_RE = re.compile(r"!\[[^\]]*\]\(\s*([^)\s]+)") +HTML_IMAGE_RE = re.compile(r"]*?\ssrc=\"([^\"]+)\"") +# Browsers cannot display these inline, so mdBook renders a broken image. +UNRENDERABLE_SUFFIXES = {".pdf", ".eps", ".tif", ".tiff"} + + +def iter_markdown_files(chapter_dir: Path): + for path in sorted(chapter_dir.rglob("*.md")): + relative = path.relative_to(chapter_dir) + if relative.parts[0] in RESOURCE_NAMES: + continue + yield path + + +def resolve_reference(chapter_dir: Path, markdown_file: Path, reference: str) -> Path: + # Resource dirs are symlinks created at build time, so resolve them manually. + target = Path(os.path.normpath(markdown_file.parent / reference)) + relative = target.relative_to(chapter_dir) if target.is_relative_to(chapter_dir) else None + if relative is not None and relative.parts and relative.parts[0] in RESOURCE_NAMES: + return SHARED_RESOURCES / relative + return target + + +class ImageReferenceTests(unittest.TestCase): + def test_chapter_images_exist_and_are_renderable(self) -> None: + problems: list[str] = [] + for chapter_dir in CHAPTER_DIRS: + for markdown_file in iter_markdown_files(chapter_dir): + text = markdown_file.read_text(encoding="utf-8") + references = MARKDOWN_IMAGE_RE.findall(text) + HTML_IMAGE_RE.findall(text) + for reference in references: + if reference.startswith(("http://", "https://", "data:")): + continue + location = f"{markdown_file.relative_to(REPO_ROOT)}: {reference}" + if Path(reference).suffix.lower() in UNRENDERABLE_SUFFIXES: + problems.append(f"unrenderable format {location}") + elif not resolve_reference(chapter_dir, markdown_file, reference).is_file(): + problems.append(f"missing file {location}") + + self.assertEqual(problems, [], "\n".join(problems)) + + +if __name__ == "__main__": + unittest.main() diff --git a/v1/en_chapters/SUMMARY.md b/v1/en_chapters/SUMMARY.md index 97f1716..37f3981 100644 --- a/v1/en_chapters/SUMMARY.md +++ b/v1/en_chapters/SUMMARY.md @@ -2,20 +2,110 @@ [Machine Learning Systems: Design and Implementation (1st Edition)](index.md) [Preface](chapter_preface/index.md) -[Introduction](chapter_introduction/index.md) -[Programming Model](chapter_programming_interface/index.md) -[Computational Graph](chapter_computational_graph/index.md) -[Part I Framework Design](chapter_preface_advanced/index.md) -[AI Compiler Frontend](chapter_frontend_and_ir/index.md) -[AI Compiler Backend](chapter_backend_and_runtime/index.md) -[Hardware Accelerator](chapter_accelerator/index.md) -[Data Processing Framework](chapter_data_processing/index.md) -[Model Deployment](chapter_model_deployment/index.md) -[Distributed Training](chapter_distributed_training/index.md) -[Part II Application Scenarios](chapter_preface_extension/index.md) -[Recommender System](chapter_recommender_system/index.md) -[Federated Learning Systems](chapter_federated_learning/index.md) -[Reinforcement Learning System](chapter_reinforcement_learning/index.md) -[Explainable AI Systems](chapter_explainable_AI/index.md) -[Robotic System](chapter_rl_sys/index.md) -[Appendix: Introduction to Machine Learning](appendix_machine_learning_introduction/index.md) + +# Fundamentals + +- [Introduction](chapter_introduction/index.md) + - [Machine Learning Applications](chapter_introduction/applications.md) + - [Design Objectives of Machine Learning Frameworks](chapter_introduction/design.md) + - [Machine Learning Framework Architecture](chapter_introduction/architecture.md) + - [Application Scenarios of Machine Learning Systems](chapter_introduction/ecosystem.md) + - [Book Organization and Intended Audience](chapter_introduction/readers.md) +- [Programming Model](chapter_programming_interface/index.md) + - [Overview](chapter_programming_interface/development_history.md) + - [Machine Learning Workflow](chapter_programming_interface/ml_workflow.md) + - [Neural Network Programming](chapter_programming_interface/neural_network_layer.md) + - [Bridging Python and C/C++ Functions](chapter_programming_interface/c_python_interaction.md) + - [Functional Programming](chapter_programming_interface/ml_programming_paradigm.md) + - [Chapter Summary](chapter_programming_interface/summary.md) +- [Computational Graph](chapter_computational_graph/index.md) + - [Computational Graph Functions](chapter_computational_graph/components_of_computational_graph.md) + - [Computational Graph Basics](chapter_computational_graph/background_and_functionality.md) + - [Generating a Computational Graph](chapter_computational_graph/generation_of_computational_graph.md) + - [Scheduling and Executing Computational Tasks](chapter_computational_graph/schedule_of_computational_graph.md) + - [Chapter Summary](chapter_computational_graph/summary.md) + +# Part I Framework Design + +- [Overview](chapter_preface_advanced/index.md) +- [AI Compiler Frontend](chapter_frontend_and_ir/index.md) + - [Overview of AI Compilers](chapter_frontend_and_ir/ai_compiler_design_principle.md) + - [Overview of AI Compiler Frontends](chapter_frontend_and_ir/overview_of_frontend.md) + - [Intermediate Representation](chapter_frontend_and_ir/intermediate_representation.md) + - [Automatic Differentiation](chapter_frontend_and_ir/ad.md) + - [Type Systems and Static Analysis](chapter_frontend_and_ir/type_system_and_static_analysis.md) + - [Frontend Compilation Optimization](chapter_frontend_and_ir/common_frontend_optimization_pass.md) + - [Chapter Summary](chapter_frontend_and_ir/summary.md) +- [AI Compiler Backend](chapter_backend_and_runtime/index.md) + - [Overview](chapter_backend_and_runtime/overview.md) + - [Graph Optimization](chapter_backend_and_runtime/graph_optimizer.md) + - [Operator Selection](chapter_backend_and_runtime/kernel_selecter.md) + - [Memory Allocation](chapter_backend_and_runtime/memory_allocator.md) + - [Computation Scheduling and Execution](chapter_backend_and_runtime/compute_schedule_and_execute.md) + - [Operator Compiler](chapter_backend_and_runtime/op_compiler.md) + - [Chapter Summary](chapter_backend_and_runtime/summary.md) +- [Hardware Accelerator](chapter_accelerator/index.md) + - [Overview](chapter_accelerator/accelerator_introduction.md) + - [Components of Hardware Accelerators](chapter_accelerator/accelerator_architecture.md) + - [Programming Methods](chapter_accelerator/accelerator_programming.md) + - [Performance Optimization Methods](chapter_accelerator/accelerator_practise.md) + - [Chapter Summary](chapter_accelerator/summary.md) +- [Data Processing Framework](chapter_data_processing/index.md) + - [Overview](chapter_data_processing/requirements.md) + - [Usability Design](chapter_data_processing/program_model.md) + - [Efficiency Design](chapter_data_processing/performance.md) + - [Order Preservation Design](chapter_data_processing/data_order.md) + - [Scaling Single-Machine Data Processing Performance](chapter_data_processing/extension.md) + - [Summary](chapter_data_processing/summary.md) +- [Model Deployment](chapter_model_deployment/index.md) + - [Overview](chapter_model_deployment/model_deployment_introduction.md) + - [Conversion to Inference Model and Model Optimization](chapter_model_deployment/model_converter_and_optimizer.md) + - [Model Compression](chapter_model_deployment/model_compression.md) + - [Model Inference](chapter_model_deployment/model_inference.md) + - [Security Protection of Models](chapter_model_deployment/model_security.md) + - [Chapter Summary](chapter_model_deployment/summary.md) +- [Distributed Training](chapter_distributed_training/index.md) + - [Overview](chapter_distributed_training/overview.md) + - [Parallelism Methods](chapter_distributed_training/methods.md) + - [Architecture of Machine Learning Clusters](chapter_distributed_training/cluster.md) + - [Collective Communication](chapter_distributed_training/collective.md) + - [Parameter Server](chapter_distributed_training/parameter_servers.md) + - [Chapter Summary](chapter_distributed_training/summary.md) + +# Part II Application Scenarios + +- [Overview](chapter_preface_extension/index.md) +- [Recommender System](chapter_recommender_system/index.md) + - [Overview](chapter_recommender_system/system_architecture.md) + - [Recommendation Pipeline](chapter_recommender_system/multi_stage_recommender_system.md) + - [Model Update](chapter_recommender_system/model_update.md) + - [Supporting Real-time Machine Learning](chapter_recommender_system/case_study.md) + - [Chapter Summary](chapter_recommender_system/summary.md) +- [Federated Learning Systems](chapter_federated_learning/index.md) + - [Overview](chapter_federated_learning/overview.md) + - [Horizontal Federated Learning](chapter_federated_learning/horizontal_fl.md) + - [Vertical Federated Learning](chapter_federated_learning/vertical_fl.md) + - [Privacy Encryption Algorithms](chapter_federated_learning/privacy_encryption_algorithm.md) + - [Outlook](chapter_federated_learning/outlook.md) + - [Summary](chapter_federated_learning/summary.md) +- [Reinforcement Learning System](chapter_reinforcement_learning/index.md) + - [Introduction to Reinforcement Learning](chapter_reinforcement_learning/rl_introduction.md) + - [Single-Node Reinforcement Learning System](chapter_reinforcement_learning/single_node_rl.md) + - [Multi-agent Reinforcement Learning](chapter_reinforcement_learning/marl.md) + - [Multi-agent Reinforcement Learning System](chapter_reinforcement_learning/marl_sys.md) + - [Chapter Summary](chapter_reinforcement_learning/summary.md) +- [Explainable AI Systems](chapter_explainable_AI/index.md) + - [Background](chapter_explainable_AI/explainable_ai.md) +- [Robotic System](chapter_rl_sys/index.md) + - [Overview of Robotic Systems](chapter_rl_sys/rl_sys_intro.md) + - [Robot Operating System](chapter_rl_sys/ros.md) + - [Case Study: Using ROS](chapter_rl_sys/ros_code_ex.md) + - [Modern Robot Learning](chapter_rl_sys/robot_learning.md) + - [Chapter Summary](chapter_rl_sys/summary.md) + +# Appendix + +- [Appendix: Introduction to Machine Learning](appendix_machine_learning_introduction/index.md) + - [Neural Networks](appendix_machine_learning_introduction/neural_network.md) + - [Gradient Descent and Backpropagation](appendix_machine_learning_introduction/gradient_descent.md) + - [Classic Machine Learning Methods](appendix_machine_learning_introduction/classic_machine_learning.md) diff --git a/v1/en_chapters/chapter_accelerator/accelerator_architecture.md b/v1/en_chapters/chapter_accelerator/accelerator_architecture.md index 06be343..4e1dbda 100644 --- a/v1/en_chapters/chapter_accelerator/accelerator_architecture.md +++ b/v1/en_chapters/chapter_accelerator/accelerator_architecture.md @@ -20,7 +20,7 @@ target market of the GPU. Figure :numref:`ch06/ch06-gv100` illustrates the architecture of the Volta GV100 . This architecture has: -![Volta GV100](../img/ch06/V100.png) +![Volta GV100](../img/ch06/V100.svg) :label:`ch06/ch06-gv100` 1. 6 GPU processing clusters (GPCs), each containing: @@ -118,7 +118,7 @@ handle various neural networks. Figure :numref:`ch06/ch06-compute-unit` demonstrates how different layers of neural networks select appropriate compute units. -![Computeunits](../img/ch06/compute_unit.png) +![Computeunits](../img/ch06/compute_unit.svg) :label:`ch06/ch06-compute-unit` 1. **Scalar Unit**: calculates one scalar element at a time, similar to @@ -145,7 +145,7 @@ floating-point arithmetic units, which are Scalar Units, and 8 Tensor Cores, which are 3D Cube Units specially designed for neural network applications. -![Volta GV100 SM](../img/ch06/SM.png) +![Volta GV100 SM](../img/ch06/SM.svg) :label:`ch06/ch06-SM` A Tensor Core is capable of performing one $4\times4$ matrix @@ -156,7 +156,7 @@ Figure :numref:`ch06/ch06-tensorcore`. D = A * B + C ``` -![Tensor Core's $4\times4$ matrix multiply-accumulateoperation](../img/ch06/tensor_core.png) +![Tensor Core's $4\times4$ matrix multiply-accumulateoperation](../img/ch06/tensor_core.svg) :label:`ch06/ch06-tensorcore` $\bf{A}$, $\bf{B}$, $\bf{C}$, and $\bf{D}$ are $4\times4$ matrices. @@ -170,7 +170,7 @@ compute units. ## Domain Specific Architecture -![Da Vinciarchitecture](../img/ch06/davinci_architecture.png) +![Da Vinciarchitecture](../img/ch06/davinci_architecture.svg) :label:`ch06/ch06-davinci_architecture` Domain Specific Architecture (DSA) has been an area of interest in diff --git a/v1/en_chapters/chapter_accelerator/accelerator_practise.md b/v1/en_chapters/chapter_accelerator/accelerator_practise.md index b1680de..b03eb39 100644 --- a/v1/en_chapters/chapter_accelerator/accelerator_practise.md +++ b/v1/en_chapters/chapter_accelerator/accelerator_practise.md @@ -68,7 +68,7 @@ row index and the column vector in matrix $B$ according to the column index, computes the vector inner product. The thread also stores the result back to $C$ matrix in line 17. -![Simple implementation ofGEMM](../img/ch06/practise/naive.png) +![Simple implementation ofGEMM](../img/ch06/6.4/naive.png) :label:`cuda_naive_gemm` The method of launching the kernel function is shown in @@ -177,7 +177,7 @@ from matrix $A$ and matrix $B$ from left to right and from top to bottom, computes the data, and stores the data to matrix $C$, as shown in Figure :numref:`use_float4`. -![Enhancing arithmeticintensity](../img/ch06/practise/use_float4.png) +![Enhancing arithmeticintensity](../img/ch06/6.4/use_float4.png) :label:`use_float4` For details about the complete code, see @@ -188,7 +188,7 @@ Figure :numref:`use_tile`. For details about the code used to achieve this, see [gemm_use_tile.cu](https://github.com/openmlsys/openmlsys-cuda/blob/main/gemm_use_tile.cu). -![Further enhancement of the arithmetic intensity by adding matrixblocks processed by eachthread](../img/ch06/practise/use_tile.png) +![Further enhancement of the arithmetic intensity by adding matrixblocks processed by eachthread](../img/ch06/6.4/use_tile.png) :label:`use_tile` The test results are as follows: @@ -256,7 +256,7 @@ shared memory can be used to improve the program throughput by enabling different threads in the same thread block to load unique data and reuse shared data. -![Threads loading redundantdata](../img/ch06/practise/duplicated_data.png) +![Threads loading redundantdata](../img/ch06/6.4/duplicated_data.png) :label:`duplicated_data` We have previously mentioned that the inner product can be computed by @@ -281,10 +281,10 @@ threads from the global memory and stores the data in the shared memory. During computational processes, each thread only needs to load the data it requires from the shared memory. -![Writing data to the sharedmemory](../img/ch06/practise/use_smem_store.png) +![Writing data to the sharedmemory](../img/ch06/6.4/use_smem_store.png) :label:`use_smem_store` -![Loading data from the sharedmemory](../img/ch06/practise/use_smem_load.png) +![Loading data from the sharedmemory](../img/ch06/6.4/use_smem_load.png) :label:`use_smem_load` For details about the complete code, see @@ -355,10 +355,10 @@ the current operation do not require the data in the next loop. As such, the execution of these computation instructions will not be blocked by the instructions that load the data for the next loop. -![Pipeline of the previous GPU kernelfunction](../img/ch06/practise/use_smem_pipeline.png) +![Pipeline of the previous GPU kernelfunction](../img/ch06/6.4/use_smem_pipeline.png) :label:`use_smem_pipeline` -![Pipeline that hides the shared memory loadinglatency](../img/ch06/practise/hide_smem_latency.png) +![Pipeline that hides the shared memory loadinglatency](../img/ch06/6.4/hide_smem_latency.png) :label:`hide_smem_latency` For details about the complete code, see @@ -398,7 +398,7 @@ written to `tile` in the last loop in the inner loop after $tileK - 1$ loops are executed, further reducing the latency of writing data to `tile`. Figure :numref:`hide_global_latency` shows the optimized pipeline. -![Pipeline that hides the global memory loadinglatency](../img/ch06/practise/hide_global_latency.png) +![Pipeline that hides the global memory loadinglatency](../img/ch06/6.4/hide_global_latency.png) :label:`hide_global_latency` For details about the complete code, see diff --git a/v1/en_chapters/chapter_accelerator/index.md b/v1/en_chapters/chapter_accelerator/index.md index 7f93d79..02dffe4 100644 --- a/v1/en_chapters/chapter_accelerator/index.md +++ b/v1/en_chapters/chapter_accelerator/index.md @@ -18,9 +18,9 @@ This chapter has the following learning objectives: ```toc :maxdepth: 2 -Overview -Components_of_Hardware_Accelerators -Programming_Methods -Performance_Optimization_Methods -Chapter_Summary +accelerator_introduction +accelerator_architecture +accelerator_programming +accelerator_practise +summary ``` diff --git a/v1/en_chapters/chapter_backend_and_runtime/graph_optimizer.md b/v1/en_chapters/chapter_backend_and_runtime/graph_optimizer.md index d946090..e80d4e2 100644 --- a/v1/en_chapters/chapter_backend_and_runtime/graph_optimizer.md +++ b/v1/en_chapters/chapter_backend_and_runtime/graph_optimizer.md @@ -27,7 +27,7 @@ fusing \"Conv + Conv + Sum + ReLU\". This fusion optimization eliminates two read operations and two write operations, optimizing the read and write of the outputs generated by Conv and Sum. -![Element-wise operatorfusion](../img/ch07/conv_sum_relu.png) +![Element-wise operatorfusion](../img/ch05/conv_sum_relu.png) :label:`ch07/ch07-compiler-backend-03` Furthermore, automatic operator generation technology enables more @@ -65,7 +65,7 @@ on general compute rules, thereby facilitating efficient execution. However, it should be noted that this approach involves additional memory movements. -![Graph kernelfusion](../img/ch07/graph_kernel.png) +![Graph kernelfusion](../img/ch05/graph_kernel.png) :label:`ch07/ch07-compiler-backend-graph-kernel` ## Hardware-Specific Optimizations @@ -88,7 +88,7 @@ split a 100-input Concat node into two smaller nodes, one with 63 inputs and the other with 37 inputs, to meet the 63-input requirement of the accelerator. -![Partitioning of the Concatoperator](../img/ch07/concat.png) +![Partitioning of the Concatoperator](../img/ch05/concat.png) :label:`ch07/ch07-compiler-backend-04` ### Memory Format Restrictions @@ -111,5 +111,5 @@ figure) are inverse operations of each other. By employing pattern matching on the computational graph, such operations can be easily eliminated. -![Elimination of format transformationoperations](../img/ch07/transdata.png) +![Elimination of format transformationoperations](../img/ch05/transdata.png) :label:`ch07/ch07-compiler-backend-05` diff --git a/v1/en_chapters/chapter_backend_and_runtime/index.md b/v1/en_chapters/chapter_backend_and_runtime/index.md index 6217342..a8e19b6 100644 --- a/v1/en_chapters/chapter_backend_and_runtime/index.md +++ b/v1/en_chapters/chapter_backend_and_runtime/index.md @@ -28,11 +28,11 @@ This chapter aims to achieve the following learning objectives: ```toc :maxdepth: 2 -Overview -Graph_Optimization -Operator_Selection -Memory_Allocation -Operator_Compiler -Chapter_Summary -Further_Reading +overview +graph_optimizer +kernel_selecter +memory_allocator +compute_schedule_and_execute +op_compiler +summary ``` diff --git a/v1/en_chapters/chapter_backend_and_runtime/kernel_selecter.md b/v1/en_chapters/chapter_backend_and_runtime/kernel_selecter.md index 23d5b50..7996a12 100644 --- a/v1/en_chapters/chapter_backend_and_runtime/kernel_selecter.md +++ b/v1/en_chapters/chapter_backend_and_runtime/kernel_selecter.md @@ -41,7 +41,7 @@ row-major order by default, as shown at the top of the figure. However, matrix **B** is read in column-major order in the matrix multiplication process, as shown at the bottom. -![Matrix data layouts in matrixmultiplication](../img/ch07/matmuldatalayout.png) +![Matrix data layouts in matrixmultiplication](../img/ch05/matmuldatalayout.png) :label:`ch07/ch07-compiler-backend-06` Storing matrix **B** in the reading order increases the computation @@ -56,7 +56,7 @@ channels, and H and W denote the height and width respectively. Figure diagram of an input with batch size 2, channels 16, height 5, and width 4. -![Formatdiagram](../img/ch07/data_format.png) +![Formatdiagram](../img/ch05/data_format.png) :label:`ch07/ch07-compiler-backend-07` A multidimensional matrix is flattened into 1D format before it is @@ -88,7 +88,7 @@ before the next channel is processed. The same procedure is repeated until the last channel of the last image is processed. NCHW is the default format on PyTorch and MindSpore. -![RGB image data in NHWCformat](../img/ch07/nchw.png) +![RGB image data in NHWCformat](../img/ch05/nchw.png) :label:`ch07/ch07-compiler-backend-08` Access to data in NHWC format also begins at the lowest dimension (i.e., @@ -109,7 +109,7 @@ to the jumps from the innermost axis to the next. For example, \[a:1\] indicates the jump from axis W to axis H, and \[b:1\] indicates the jump from axis C (the innermost) to axis W. -![NCHW and NHWCformats](../img/ch07/nchwandnhwc.png) +![NCHW and NHWCformats](../img/ch05/nchwandnhwc.png) :label:`ch07/ch07-compiler-backend-nchwandnhwc` These two formats offer a high degree of flexibility and are therefore @@ -141,7 +141,7 @@ In Figure :numref:`ch07/ch07-float32andfloat16`, *Sig* refers to the sign bit that indicates the sign of a number, *Exponent* refers to the exponent bits, and *Mantissa* refers to the mantissa bits. -![Binary representation of floating-pointnumbers](../img/ch07/floatdtype.png) +![Binary representation of floating-pointnumbers](../img/ch05/floatdtype.png) :label:`ch07/ch07-float32andfloat16` Applying Equation @@ -190,7 +190,7 @@ types, and execution efficiency of a given operator vary depending on the target hardware. Then, the compiler backend selects an operator based on the data type and data format derived from the IR. -![Operator selection process (using GPU as anexample)](../img/ch07/select_kernel.png) +![Operator selection process (using GPU as anexample)](../img/ch05/select_kernel.png) :label:`ch07/ch07-compiler-backend-select` The result of the operator selection process might not be as expected diff --git a/v1/en_chapters/chapter_backend_and_runtime/memory_allocator.md b/v1/en_chapters/chapter_backend_and_runtime/memory_allocator.md index 575a7ce..864aaf4 100644 --- a/v1/en_chapters/chapter_backend_and_runtime/memory_allocator.md +++ b/v1/en_chapters/chapter_backend_and_runtime/memory_allocator.md @@ -28,7 +28,7 @@ that the device can directly access the data. When the computation is finished, the user can obtain the training result once the result data is copied from the device memory back to the host memory. -![Host memory and devicememory](../img/ch07/host-device-memory.png) +![Host memory and devicememory](../img/ch05/host-device-memory.png) :label:`ch07/ch07-compiler-backend-memory-01` ## Process of Memory Allocation @@ -57,7 +57,7 @@ Figure :numref:`ch07/ch07-compiler-backend-memory-02` illustrates an example of memory allocation. -![Memory allocationexample](../img/ch07/memory_allocate.png) +![Memory allocationexample](../img/ch05/memory_allocate.png) :label:`ch07/ch07-compiler-backend-memory-02` In this example, memory addresses are assigned to the input tensor, @@ -94,7 +94,7 @@ operator memory to be allocated using offset pointers from pre-allocated device memory, significantly reducing the time required compared to direct memory allocations from the device. -![Memory allocation using double offsetpointers](../img/ch07/device_malloc.png) +![Memory allocation using double offsetpointers](../img/ch05/device_malloc.png) :label:`ch07/ch07-compiler-backend-memory-03` ## Memory Reuse @@ -129,7 +129,7 @@ in the same memory. In Figure accommodate only four rectangular blocks (i.e., tensors T0, T1, T2, and T3) when no memory reuse policy is applied, as shown in the left chart. -![Memory lifetimecharts](../img/ch07/combine_memory_resue_and_no_reuse_cn.png) +![Memory lifetimecharts](../img/ch05/combine_memory_reuse_and_no_reuse.png) :label:`ch07/ch07-compiler-backend-memory-04` To determine an appropriate memory reuse policy, we face an NP-complete @@ -182,7 +182,7 @@ in this scenario, a typical approach is to allocate contiguous memory addresses to all weights on the network and then perform a single broadcast operation. -![Memory fusion of communicationoperators](../img/ch07/memory_fusion.png) +![Memory fusion of communicationoperators](../img/ch05/memory_fusion.png) :label:`ch07/ch07-compiler-backend-memory-06` ### In-place Operators @@ -209,7 +209,7 @@ simplified to a single step: copying tensor `b` to the position corresponding to tensor `a`. This reduces data copy time by eliminating two copies and eliminates the need to allocate memory for tensor `a’`. -![Memory allocation of an in-placeoperator](../img/ch07/inplace-op.png) +![Memory allocation of an in-placeoperator](../img/ch05/inplace-op.png) :label:`ch07/ch07-compiler-backend-memory-08` ## Data Compression diff --git a/v1/en_chapters/chapter_backend_and_runtime/overview.md b/v1/en_chapters/chapter_backend_and_runtime/overview.md index e8011d0..9bd1f70 100644 --- a/v1/en_chapters/chapter_backend_and_runtime/overview.md +++ b/v1/en_chapters/chapter_backend_and_runtime/overview.md @@ -4,7 +4,7 @@ Figure :numref:`ch07/ch07-compiler-backend-01` illustrates the architecture of the AI compiler backend, situated between the frontend and the hardware driver layer. -![Architecture of AI compilerbackend](../img/ch07/compiler-backend-architecture.pdf) +![Architecture of AI compilerbackend](../img/ch05/compiler-backend-architecture.png) :label:`ch07/ch07-compiler-backend-01` Graph optimization is a crucial step that involves transforming the diff --git a/v1/en_chapters/chapter_computational_graph/background_and_functionality.md b/v1/en_chapters/chapter_computational_graph/background_and_functionality.md index 3daaa5d..865f73e 100644 --- a/v1/en_chapters/chapter_computational_graph/background_and_functionality.md +++ b/v1/en_chapters/chapter_computational_graph/background_and_functionality.md @@ -7,7 +7,7 @@ dependencies between operators. Figure :numref:`ch04/ch04-simpleDAG` shows a computational graph example of $\bf{Z}$=ReLU$(\bf{X}\times\bf{Y})$. -![Simple computationalgraph](../img/ch04/simple-graph.png) +![Simple computationalgraph](../img/ch03/simpledag.png) :label:`ch04/ch04-simpleDAG` ## Tensors and Operators @@ -20,7 +20,7 @@ vector is a rank-1 tensor with one axis; and a three-channel RGB color image is a rank-3 tensor with three axes. See Figure :numref:`ch04/ch04-tensor`. -![Tensors](../img/ch04/tensor.png) +![Tensors](../img/ch03/tensor.png) :label:`ch04/ch04-tensor` In a machine learning framework, a tensor stores not only data itself @@ -78,7 +78,7 @@ Sparse tensors often handle graph data of graph neural networks (GNNs) and are encoded using special formats such as the coordinate list (COO) to improve storage efficiency. -![Types of tensors](../img/ch04/tensor-class.png) +![Types of tensors](../img/ch03/tensorclass.svg) :label:`ch04/ch04-tensor1` Operators are the basic compute units of neural networks. They process @@ -143,7 +143,7 @@ activation function, and the data flow will be interrupted. We can therefore conclude that the operators in this computational graph depend on each other with transitive relations. -![Computationaldependencies](../img/ch04/dependence.png) +![Computationaldependencies](../img/ch03/dependence.svg) :label:`ch04/ch04-dependence` Three types of dependencies are available. @@ -174,7 +174,7 @@ underflow to negative infinity, or tend to 0. These all lead to unexpected training results. As such, we should avoid circular dependencies between operators when designing deep learning models. -![Circulardependency](../img/ch04/recurrent.png) +![Circulardependency](../img/ch03/recurrent.svg) :label:`ch04/ch04-recurrent` In machine learning frameworks, the *unrolling* method is used to @@ -192,7 +192,7 @@ with unique identifiers. When a subgraph is replicated to produce an unrolled loop, the replicated tensors and operators are assigned new identifiers to avoid circular dependencies. -![Unrolled loop](../img/ch04/unroll.png) +![Unrolled loop](../img/ch03/unroll.png) :label:`ch04/ch04-recurrent-1` ## Control Flows @@ -289,7 +289,7 @@ participate in computation due to conditional control. Similarly, in the backward computational graph, tensor $\bf{C}$ is skipped in gradient computation. -![Computational graphs of conditionalcontrol](../img/ch04/if.png) +![Computational graphs of conditionalcontrol](../img/ch03/if.png) :label:`ch04/ch04-if` A control loop allows us to execute an operation in a loop zero or @@ -324,7 +324,7 @@ also a loop, with the same number of iterations as the forward loop. The gradient value output by one iteration serves as the input value for calculating the gradient of the next iteration until the loop ends. -![Computational graphs of loopcontrol](../img/ch04/while.png) +![Computational graphs of loopcontrol](../img/ch03/while.png) :label:`ch04/ch04-while` ## Gradient Computation Using the Chain Rule @@ -384,7 +384,7 @@ backpropagation based on the error between the output value and label value to update the weight parameters to minimize the error. The weight parameters to be updated include $\bf{W}$ and $\bf{W_1}$. -![Backpropagation computationalgraph](../img/ch04/chain.png) +![Backpropagation computationalgraph](../img/ch03/chain.png) :label:`ch04/ch04-chain` The mean square error (MSE) is selected as the loss function in this diff --git a/v1/en_chapters/chapter_computational_graph/components_of_computational_graph.md b/v1/en_chapters/chapter_computational_graph/components_of_computational_graph.md index 823fe9c..c00494a 100644 --- a/v1/en_chapters/chapter_computational_graph/components_of_computational_graph.md +++ b/v1/en_chapters/chapter_computational_graph/components_of_computational_graph.md @@ -21,7 +21,7 @@ decoupling the frontend and backend languages in design, as shown in Figure :numref:`ch04/ch04-DAG`. From a top-level view, computational graph technology provides the following key functions: -![Computational graph--basedarchitecture](../img/ch04/graph.png) +![Computational graph--basedarchitecture](../img/ch03/graph.png) :label:`ch04/ch04-DAG` 1. **Unified representation of the computation process.** Developers diff --git a/v1/en_chapters/chapter_computational_graph/generation_of_computational_graph.md b/v1/en_chapters/chapter_computational_graph/generation_of_computational_graph.md index a750c1d..3488932 100644 --- a/v1/en_chapters/chapter_computational_graph/generation_of_computational_graph.md +++ b/v1/en_chapters/chapter_computational_graph/generation_of_computational_graph.md @@ -26,7 +26,7 @@ The static graph approach decouples the definition and execution processes. That is, a static graph is compiled before it is executed, as shown in Figure :numref:`ch04/ch04-static`. -![Generating and executing a staticgraph](../img/ch04/static.png) +![Generating and executing a staticgraph](../img/ch03/static.png) :label:`ch04/ch04-static` When a model program is generated using the frontend language, the @@ -81,7 +81,7 @@ learning frameworks are able to compile Python control flows as their static graph equivalents. In order to implement control flows in this case, we can use the control primitives provided by the framework. -![Generating a staticgraph](../img/ch04/static_gen.png) +![Generating a staticgraph](../img/ch03/static_gen.png) :label:`ch04/ch04-static-gen` Static computational graphs offer two distinct advantages. First, they @@ -133,7 +133,7 @@ paradigm, the dynamic graph approach allows developers to create neural network models at the frontend and is therefore favored by a vast number of deep learning researchers. -![Dynamic graph principle](../img/ch04/eager.png) +![Dynamic graph principle](../img/ch03/eager.png) :label:`ch04/ch04-eager1` Next, we reuse the pseudocode in the previous section to compare the @@ -154,7 +154,7 @@ computational dependencies, and dynamically generates a temporary graph. Figure :numref:`ch04/ch04-dynamic-gen` shows the process of generating a dynamic graph. -![Generating a dynamicgraph](../img/ch04/eager-gen.png) +![Generating a dynamicgraph](../img/ch03/eager-gen.png) :label:`ch04/ch04-dynamic-gen` Forward computation is run through the neural network in the sequence @@ -362,7 +362,7 @@ into the corresponding static graph API in this phase, so as to include every branch of the control flow in the resulting graph. Next, we can easily generate static graph code from the translated syntax tree. -![Source code transformation](../img/ch04/ast.png) +![Source code transformation](../img/ch03/ast.svg) :label:`ch04/ch04-ast` In numerous instances, the utilization of either tracing or source code diff --git a/v1/en_chapters/chapter_computational_graph/index.md b/v1/en_chapters/chapter_computational_graph/index.md index 0bf2eaf..4453b29 100644 --- a/v1/en_chapters/chapter_computational_graph/index.md +++ b/v1/en_chapters/chapter_computational_graph/index.md @@ -18,10 +18,9 @@ this technology, this chapter explains the following key aspects: ```toc :maxdepth: 2 -Computational_Graph_Functions -Computational_Graph_Basics -Generating_a_Computational_Graph -Scheduling_and_Executing_Computational_Tasks -Chapter_Summary -Further_Reading +components_of_computational_graph +background_and_functionality +generation_of_computational_graph +schedule_of_computational_graph +summary ``` diff --git a/v1/en_chapters/chapter_computational_graph/schedule_of_computational_graph.md b/v1/en_chapters/chapter_computational_graph/schedule_of_computational_graph.md index 2eca701..6469b5f 100644 --- a/v1/en_chapters/chapter_computational_graph/schedule_of_computational_graph.md +++ b/v1/en_chapters/chapter_computational_graph/schedule_of_computational_graph.md @@ -42,7 +42,7 @@ a). According to the operator call sequence of the model code, such as a-\>b-\>c-\>d-\>e, all operator nodes are put into the queue in turn, and the scheduling ends. -![Operator scheduling andexecution](../img/ch04/schedule.png) +![Operator scheduling andexecution](../img/ch03/schedule.svg) :label:`ch04/ch04-diaoduzhixing` With the ordering, we then prepare to distribute the operators in the @@ -107,7 +107,7 @@ upstream. As such, we have to schedule the operators in this computational graph to a serial queue in order to ensure that each operator receives the necessary input. -![Serial operatorscheduling](../img/ch04/order.png) +![Serial operatorscheduling](../img/ch03/order.png) :label:`ch04/ch04-diaodu` A computational graph may also contain operators independent of each @@ -117,7 +117,7 @@ different hardware devices to implement parallel computing. Compared with the serial mode, parallel computing decreases execution time by leveraging more computing resources at the same time. -![Parallel operator scheduling](../img/ch04/para.png) +![Parallel operator scheduling](../img/ch03/para.svg) :label:`ch04/ch04-para` Serial execution and parallel execution have their own advantages and @@ -217,7 +217,7 @@ preprocessing and model training tasks must wait until a batch of data is completely loaded, and because the I/O channel for data loading is idle at model training time. -![Synchronous mechanism](../img/ch04/sync.png) +![Synchronous mechanism](../img/ch03/synchronization.svg) :label:`ch04/ch04-tongbu` In the asynchronous setting shown in Figure @@ -229,7 +229,7 @@ idle time between data loading, data preprocessing, and model training in the asynchronous mechanism is notably reduced, thereby shortening the overall training time with improved execution efficiency. -![Asynchronous mechanism](../img/ch04/async.png) +![Asynchronous mechanism](../img/ch03/asynchronous.svg) :label:`ch04/ch04-yibu` To further shorten the training time and improve the execution @@ -241,5 +241,5 @@ and preprocessing, allowing the model to quickly traverse the entire dataset. On the other hand, parallel computing increases the batch size in iterative training, increasing the efficiency of computing resources. -![Asynchronous mechanism combined with parallelcomputing](../img/ch04/para-async.png) +![Asynchronous mechanism combined with parallelcomputing](../img/ch03/asyn_para.svg) :label:`ch04/ch04-yibubingxing` diff --git a/v1/en_chapters/chapter_data_processing/program_model.md b/v1/en_chapters/chapter_data_processing/program_model.md index 3d67bdf..e1a5be7 100644 --- a/v1/en_chapters/chapter_data_processing/program_model.md +++ b/v1/en_chapters/chapter_data_processing/program_model.md @@ -28,7 +28,7 @@ val count = ones.reduce(_+_) We can see that users need only four lines of code to accomplish the complex task of counting specific field occurrences in a distributed dataset. This is made possible by Spark's core RDD programming abstraction. From the computation flow visualization in :numref:`rdd_transformation_example`, we can also clearly see that after creating the dataset, users only need to describe the operators applied to the dataset, while the execution and implementation of the operators are handled by the system's runtime. -![The core of Spark programming --- RDD transformations](../img//ch07/7.2/RDD.png) +![The core of Spark programming --- RDD transformations](../img/ch07/7.2/RDD.png) :width:`800px` :label:`rdd_transformation_example` diff --git a/v1/en_chapters/chapter_distributed_training/cluster.md b/v1/en_chapters/chapter_distributed_training/cluster.md index 03ec17e..4e51a03 100644 --- a/v1/en_chapters/chapter_distributed_training/cluster.md +++ b/v1/en_chapters/chapter_distributed_training/cluster.md @@ -35,7 +35,7 @@ restrict network communication within individual racks. This approach has become a core design requirement for distributed machine learning systems. -![Architecture of a machine learningcluster](../img/ch10/ch10-datacentre.png) +![Architecture of a machine learningcluster](../img/ch09/ch10-datacentre.png) :label:`ch010/ch10-datacentre` So, how much network bandwidth is required for training a large-scale diff --git a/v1/en_chapters/chapter_distributed_training/collective.md b/v1/en_chapters/chapter_distributed_training/collective.md index c163236..6ab8fe8 100644 --- a/v1/en_chapters/chapter_distributed_training/collective.md +++ b/v1/en_chapters/chapter_distributed_training/collective.md @@ -18,7 +18,7 @@ communication before introducing commonly used collective communication operators. These include Broadcast, Reduce, AllGather, Scatter, and AllReduce: -![Examples of collective communicationoperators](../img/ch10/ch10-collective-operators.png) +![Examples of collective communicationoperators](../img/ch09/ch10-collective-operators.png) :label:`ch010/ch10-collective-operators` - **Broadcast**: The Broadcast operator is often employed in a @@ -130,7 +130,7 @@ devices 1 and 3 are paired to jointly complete the summation of data in partition 3, and devices 3 and 2 are paired to jointly complete the summation of data in partition 2. -![Process of the AllReducealgorithm](../img/ch10/ch10-allreduce-process.png) +![Process of the AllReducealgorithm](../img/ch09/ch10-allreduce-process.png) :label:`ch010/ch10-allreduce-process` Such distributed computing of gradients performed by Reduce operators diff --git a/v1/en_chapters/chapter_distributed_training/index.md b/v1/en_chapters/chapter_distributed_training/index.md index c1a177a..2c45b96 100644 --- a/v1/en_chapters/chapter_distributed_training/index.md +++ b/v1/en_chapters/chapter_distributed_training/index.md @@ -40,15 +40,11 @@ The key learning objectives of this chapter are as follows: ```toc :maxdepth: 2 -Overview -Parallelism_Methods -Pipeline_Parallelism_with_Micro-Batching -Architecture_of_Machine_Learning_Clusters -Collective_Communication -Parameter_Server -Federated_Learning -Training_Large_Language_Models -Chapter_Summary -Further_Reading +overview +methods +cluster +collective +parameter_servers +summary ``` diff --git a/v1/en_chapters/chapter_distributed_training/methods.md b/v1/en_chapters/chapter_distributed_training/methods.md index 8c49020..dc03689 100644 --- a/v1/en_chapters/chapter_distributed_training/methods.md +++ b/v1/en_chapters/chapter_distributed_training/methods.md @@ -18,7 +18,7 @@ network, we employ a computational graph, comprising connected operators. Each operator executes a layer of the neural network, storing parameters to be updated during the training. -![Single-node trainingsystem](../img/ch10/ch10-single-node.png) +![Single-node trainingsystem](../img/ch09/ch10-single-node.png) :label:`ch010/ch10-single-node` The execution of a computational graph involves two phases: *forward* @@ -83,7 +83,7 @@ devices (e.g., gradient 1 on device 1 and gradient 1 on device 2) are aggregated (typically by AllReduce, a collective communication operation) to calculate an average gradient. -![Data-parallelsystem](../img/ch10/ch10-data-parallel.png) +![Data-parallelsystem](../img/ch09/ch10-data-parallel.png) :label:`ch010/ch10-data-parallel` ## Model Parallelism @@ -121,7 +121,7 @@ completes backward computation based on the local partition of operator 1. The local computation results on the devices are aggregated and returned to complete the backward computation process. -![Model-parallel system: intra-operatorparallelism](../img/ch10/ch10-model-parallel-intra-op.png) +![Model-parallel system: intra-operatorparallelism](../img/ch09/ch10-model-parallel-intra-op.png) :label:`ch010/ch10-model-parallel-intra-op` In some cases, the overall model --- rather than specific operators --- @@ -144,7 +144,7 @@ backward computation, device 2 sends the backward computation result of operator 2 to device 1 for backward computation of operator 1, completing the training on a mini-batch. -![Model-parallel system: inter-operatorparallelism](../img/ch10/ch10-model-parallel-inter-op.png) +![Model-parallel system: inter-operatorparallelism](../img/ch09/ch10-model-parallel-inter-op.png) :label:`ch010/ch10-model-parallel-inter-op` ## Hybrid Parallelism @@ -170,5 +170,5 @@ local gradients are averaged by using the AllReduce operation. The averaged gradient is back-propagated to the replicas of operator 1 on devices 1 and 3, and the backward computation process ends. -![Hybrid-parallelsystem](../img/ch10/ch10-hybrid-parallel.png) +![Hybrid-parallelsystem](../img/ch09/ch10-hybrid-parallel.png) :label:`ch010/ch10-hybrid-parallel` diff --git a/v1/en_chapters/chapter_distributed_training/overview.md b/v1/en_chapters/chapter_distributed_training/overview.md index a70dcba..d405e67 100644 --- a/v1/en_chapters/chapter_distributed_training/overview.md +++ b/v1/en_chapters/chapter_distributed_training/overview.md @@ -46,7 +46,7 @@ expansive data centers and cloud computing facilities and managing them effectively through distributed training systems, we can cater to the surging computational requirements of evolving models. -![Machine Learning Model Size vs. Hardware ComputationalCapability](../img/ch10/ch10-computation-increase.png) +![Machine Learning Model Size vs. Hardware ComputationalCapability](../img/ch09/ch10-computation-increase.png) :label:`ch010/ch10-computation-increase` ### Memory Constraints @@ -77,7 +77,7 @@ distributed training. We can harness the power of numerous servers in a distributed training system to parallelly train a machine learning model. -![Comparison between single-node computing and multi-Node distributedcomputing](../img/ch10/ch10-single-vs-multi.png) +![Comparison between single-node computing and multi-Node distributedcomputing](../img/ch09/ch10-single-vs-multi.png) :label:`ch010/ch10-single-vs-multi` For enhancing the efficiency of the distributed training system, it is diff --git a/v1/en_chapters/chapter_distributed_training/parameter_servers.md b/v1/en_chapters/chapter_distributed_training/parameter_servers.md index 9459140..a2e3722 100644 --- a/v1/en_chapters/chapter_distributed_training/parameter_servers.md +++ b/v1/en_chapters/chapter_distributed_training/parameter_servers.md @@ -8,7 +8,7 @@ while TensorFlow and MindSpore come with built-in parameter server implementations, PyTorch requires users to implement the parameter servers themselves by using RPC interfaces. -![Architecture of a parameter serversystem](../img/ch10/ch10-parameter-servers.png) +![Architecture of a parameter serversystem](../img/ch09/ch10-parameter-servers.png) :label:`ch010/ch10-parameter-servers` ## System Architecture diff --git a/v1/en_chapters/chapter_frontend_and_ir/ad.md b/v1/en_chapters/chapter_frontend_and_ir/ad.md index fbf7600..f90dc96 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/ad.md +++ b/v1/en_chapters/chapter_frontend_and_ir/ad.md @@ -190,12 +190,12 @@ particularly important when dealing with functions of multiple variables, with each mode having specific use cases and efficiency implications. -![Computational graph of the examplefunction](../img/ch04/AD-example_graph.png) +![Computational graph of the examplefunction](../img/ch04/自动微分-示例计算图.svg) :label:`ch04/ch04-calculation_graph` ### Forward Mode -![Illustration of forward-mode automaticdifferentiation](../img/ch04/AD-forward_example.png) +![Illustration of forward-mode automaticdifferentiation](../img/ch04/自动微分-前向模式自动微分示例.png) :label:`ch04/ch04-forward-mode-compute-function` Figure :numref:`ch04/ch04-forward-mode-compute-function` elucidates thecomputation process within the forward mode. The sequence of elementaryoperations, derived from the source program, is displayed on the left.Following the chain rule and using established derivative evaluationrules, we sequentially compute each intermediate variable ${\dot{v}_i}=\frac{\partial v_i}{\partial x_1}$ from top to bottom, as depicted on the right. @@ -234,7 +234,7 @@ leveraging the chain rule and established derivative evaluation rules ${\bar{x}_1}=\frac{\partial y}{\partial x_1}$ and ${\bar{x}_2}=\frac{\partial y}{\partial x_2}$. -![Illustration of reverse-mode automaticdifferentiation](../img/ch04/AD-backward_example.png) +![Illustration of reverse-mode automaticdifferentiation](../img/ch04/自动微分-反向模式自动微分示例.png) :label:`ch04/ch04-backward-mode-compute` Every reverse pass of function $f$ produces partial derivatives of asingle output with respect to all inputs, represented by the followingvectors. This corresponds to a single row of the Jacobian matrix.Consequently, executing $m$ reverse passes gives us the full Jacobianmatrix. diff --git a/v1/en_chapters/chapter_frontend_and_ir/ai_compiler_design_principle.md b/v1/en_chapters/chapter_frontend_and_ir/ai_compiler_design_principle.md index f7b3e5f..c793fb7 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/ai_compiler_design_principle.md +++ b/v1/en_chapters/chapter_frontend_and_ir/ai_compiler_design_principle.md @@ -16,7 +16,7 @@ compilers like the Low Level Virtual Machine (LLVM). Thus, gaining an understanding of the basic architecture of the LLVM compiler, depicted in Figure :numref:`ch04/llvm-basic`, will be beneficial. -![Basic architecture of the LLVMcompiler](../img/ch04/LLVM_basic_architecture.png) +![Basic architecture of the LLVMcompiler](../img/ch04/LLVM基础结构.png) :label:`ch04/llvm-basicwidth="\\linewidth"` The LLVM compiler consists of three components: the frontend, @@ -82,5 +82,5 @@ In this process, the compiler frontend handles graph compilation and hardware-agnostic optimization, while the compiler backend conducts tasks like hardware-specific optimization and operator selection. -![Working process of MindSpore's AIcompiler](../img/ch04/compiler_process.png) +![Working process of MindSpore's AIcompiler](../img/ch04/编译器整体流程.png) :label:`ch04/msflowwidth="\\linewidth"` diff --git a/v1/en_chapters/chapter_frontend_and_ir/common_frontend_optimization_pass.md b/v1/en_chapters/chapter_frontend_and_ir/common_frontend_optimization_pass.md index 769604a..59c12b8 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/common_frontend_optimization_pass.md +++ b/v1/en_chapters/chapter_frontend_and_ir/common_frontend_optimization_pass.md @@ -26,7 +26,7 @@ types and sequence of optimization operations. These adjustments are contingent upon the set level of compilation optimization, as illustrated in Figure :numref:`ch06/ch06-opt-pass`. -![Structural layout of an optimization pass in compilationoptimization](../img/ch04/optimization_pass.png) +![Structural layout of an optimization pass in compilationoptimization](../img/ch04/编译优化-pass结构.svg) :label:`ch06/ch06-opt-pass` ## Prevalent Optimization Methods @@ -48,7 +48,7 @@ code can decrease the size of IRs and expedite both the compilation and execution of a program. These types of code can result from human errors or may manifest during other compilation optimizations. -![Elimination of deadcode](../img/ch04/dead_code_elimination.png) +![Elimination of deadcode](../img/ch04/编译优化-无用代码消除.svg) :label:`ch06/ch06-opt-pass-useless-code0-elimination` In Chapter @@ -70,7 +70,7 @@ compilation. Figure :numref:`ch06/ch06-opt-pass-constant-broadcast` depicts these two methods. -![Constant propagation and constant foldingtechniques](../img/ch04/constant_propagation_and_constant_folding.png) +![Constant propagation and constant foldingtechniques](../img/ch04/编译优化-常量传播与常量折叠.svg) :label:`ch06/ch06-opt-pass-constant-broadcast` ### Common Subexpression Elimination @@ -84,7 +84,7 @@ Figure :numref:`ch06/ch06-opt-pass-CSE`. As such, E doesn't need to be computed again; it can be directly replaced with the expression result obtained from the preceding computation. -![Common subexpression eliminationprocess](../img/ch04/common_subexpression_elimination.png) +![Common subexpression eliminationprocess](../img/ch04/编译优化-公共子表达式消除.svg) :label:`ch06/ch06-opt-pass-CSE` Common subexpression elimination, like the elimination of dead code and diff --git a/v1/en_chapters/chapter_frontend_and_ir/index.md b/v1/en_chapters/chapter_frontend_and_ir/index.md index 05f077d..ba96bb0 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/index.md +++ b/v1/en_chapters/chapter_frontend_and_ir/index.md @@ -27,12 +27,11 @@ The learning objectives of this chapter include: ```toc :maxdepth: 2 -Overview_of_AI_Compilers -Overview_of_AI_Compiler_Frontends -Intermediate_Representation -Automatic_Differentiation -Type_Systems_and_Static_Analysis -Frontend_Compilation_Optimization -Chapter_Summary -Further_Reading +ai_compiler_design_principle +overview_of_frontend +intermediate_representation +ad +type_system_and_static_analysis +common_frontend_optimization_pass +summary ``` diff --git a/v1/en_chapters/chapter_frontend_and_ir/intermediate_representation.md b/v1/en_chapters/chapter_frontend_and_ir/intermediate_representation.md index 1922c08..eaba9b5 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/intermediate_representation.md +++ b/v1/en_chapters/chapter_frontend_and_ir/intermediate_representation.md @@ -28,7 +28,7 @@ analyzing and optimizing IRs, the optimizer enhances the extensibility of the compilation process and minimizes the impact that might be introduced during an optimization process on the frontend and backend. -![Compiler's optimizationprocess](../img/ch04/IR-IR_structure.png) +![Compiler's optimizationprocess](../img/ch04/中间表示-中间表示结构.png) :label:`ch04/ch04-IR` With the ongoing evolution of compiler techniques, the development of @@ -82,7 +82,7 @@ operands and one target). Figure :numref:`ch04/ch04-linearIR` illustrates the stack machine code and three-address code representations for the expression $a-b*5$. -![Stack machine code and three-addresscode](../img/ch04/IR-linear_IR.png) +![Stack machine code and three-addresscode](../img/ch04/中间表示-线性中间表示.png) :label:`ch04/ch04-linearIR` ### Graphical Intermediate Representation @@ -104,7 +104,7 @@ shared by multiple parent nodes. By reusing subtrees, the DAG reduces the cost of the evaluation process, especially when the compiler can verify that the value of $a$ remains constant. -![AST and DAG](../img/ch04/IR-ASTDAG.png) +![AST and DAG](../img/ch04/中间表示-ASTDAG.svg) :label:`ch04/ch04-AST_DAG` ### Hybrid Intermediate Representation @@ -127,7 +127,7 @@ control transfer between these blocks is implemented through edges. This combination of linear IR for basic blocks and graphical IR for control flow allows for a flexible and efficient representation in LLVM IR. -![LLVM IR](../img/ch04/IR-LLVMIR.png) +![LLVM IR](../img/ch04/中间表示-LLVMIR.png) :label:`ch04/ch04-LLVM_IR` ## Intermediate Representation in Machine Learning Frameworks @@ -340,7 +340,7 @@ that can be performed at two adjacent levels can be a conundrum for framework developers. Finally, defining distinct operator granularities at different levels might impact accuracy to a certain degree. -![TensorFlow's IRdesign](../img/ch04/IR-MLIR.png) +![TensorFlow's IRdesign](../img/ch04/中间表示-MLIR.png) :label:`ch04/ch04-tensorflow_ecosystem` ### Multi-Level Intermediate Representation @@ -464,7 +464,7 @@ ParameterNode signifies the function's formal parameter, and CNode (corresponding to a compound expression in ANF) indicates function invocation. -![MindIR grammar](../img/ch04/IR-MindIR.png) +![MindIR grammar](../img/ch04/中间表示-MindIR.png) :label:`ch04/ch04-MindIR` The example provided below in Code 1 offers a deeper analysis of MindIR. diff --git a/v1/en_chapters/chapter_frontend_and_ir/overview_of_frontend.md b/v1/en_chapters/chapter_frontend_and_ir/overview_of_frontend.md index 12a5500..0762b4b 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/overview_of_frontend.md +++ b/v1/en_chapters/chapter_frontend_and_ir/overview_of_frontend.md @@ -12,7 +12,7 @@ concentrates on IRs and automatic differentiation, and later provides a succinct introduction to basic compiler concepts, including type systems, static analysis, and frontend optimization. -![Typical structure of an AI compilerfrontend](../img/ch04/compiler_frontend_structure.png) +![Typical structure of an AI compilerfrontend](../img/ch04/编译器前端基础架构.svg) :label:`ch04/compiler_frontend_structure` An **Intermediate Representation** is a data structure, or a form of diff --git a/v1/en_chapters/chapter_frontend_and_ir/type_system_and_static_analysis.md b/v1/en_chapters/chapter_frontend_and_ir/type_system_and_static_analysis.md index a3c2ce1..1cc1915 100644 --- a/v1/en_chapters/chapter_frontend_and_ir/type_system_and_static_analysis.md +++ b/v1/en_chapters/chapter_frontend_and_ir/type_system_and_static_analysis.md @@ -124,5 +124,5 @@ module, cache module, semantics inference module, and control flow processing module, as illustrated in Figure :numref:`ch04/ch04-compiler-frontend`. -![Static analysismodule](../img/ch04/static_analysis_module.png) +![Static analysismodule](../img/ch04/静态分析-静态分析模块.png) :label:`ch04/ch04-compiler-frontend` diff --git a/v1/en_chapters/chapter_introduction/architecture.md b/v1/en_chapters/chapter_introduction/architecture.md index 3614679..600f66f 100644 --- a/v1/en_chapters/chapter_introduction/architecture.md +++ b/v1/en_chapters/chapter_introduction/architecture.md @@ -3,7 +3,7 @@ Figure :numref:`intro/framework-architecture` shows the basic architecture of a typical, complete machine learning framework. -![Architecture of a machine learningframework](../img/intro/framework-architecture.png) +![Architecture of a machine learningframework](../img/ch01/framework-architecture.png) :label:`intro/framework-architecture` 1. **Programming interfaces:** A machine learning framework needs to diff --git a/v1/en_chapters/chapter_introduction/ecosystem.md b/v1/en_chapters/chapter_introduction/ecosystem.md index f0185c9..f6735bc 100644 --- a/v1/en_chapters/chapter_introduction/ecosystem.md +++ b/v1/en_chapters/chapter_introduction/ecosystem.md @@ -8,7 +8,7 @@ and execute machine learning applications. Figure :numref:`intro/system-ecosystem` provides an overview of the various application scenarios for machine learning systems. -![Application scenarios of machine learningsystems](../img/intro/system-ecosystem.png) +![Application scenarios of machine learningsystems](../img/ch01/system-ecosystem.png) :label:`intro/system-ecosystem` 1. **Federated learning:** Laws and regulations on user privacy diff --git a/v1/en_chapters/chapter_introduction/index.md b/v1/en_chapters/chapter_introduction/index.md index 2a21f6a..c29d180 100644 --- a/v1/en_chapters/chapter_introduction/index.md +++ b/v1/en_chapters/chapter_introduction/index.md @@ -7,12 +7,12 @@ ```toc - :maxdepth: 2 - - Machine_Learning_Applications - Design_Objectives_of_Machine_Learning_Frameworks - Machine_Learning_Framework_Architecture - Application_Scenarios_of_Machine_Learning_Systems - Book_Organization_and_Intended_Audience - ``` +:maxdepth: 2 + +applications +design +architecture +ecosystem +readers +``` \ No newline at end of file diff --git a/v1/en_chapters/chapter_model_deployment/index.md b/v1/en_chapters/chapter_model_deployment/index.md index ec00ccc..628dfa0 100644 --- a/v1/en_chapters/chapter_model_deployment/index.md +++ b/v1/en_chapters/chapter_model_deployment/index.md @@ -24,13 +24,11 @@ The key aspects this chapter explores are as follows: ```toc :maxdepth: 2 -Overview -Conversion_to_Inference_Model_and_Model_Optimization -Model_Compression -Advanced_Efficient_Techniques -Model_Inference -Security_Protection_of_Models -Chapter_Summary -Further_Reading +model_deployment_introduction +model_converter_and_optimizer +model_compression +model_inference +model_security +summary ``` diff --git a/v1/en_chapters/chapter_model_deployment/model_compression.md b/v1/en_chapters/chapter_model_deployment/model_compression.md index ad8131c..0e02ab1 100644 --- a/v1/en_chapters/chapter_model_deployment/model_compression.md +++ b/v1/en_chapters/chapter_model_deployment/model_compression.md @@ -22,7 +22,7 @@ the memory usage during inference can be reduced, and the inference on processors that are good at processing low-precision operations can be accelerated. -![Principles ofquantization](../img/ch08/ch09-quant-minmax.png) +![Principles ofquantization](../img/ch08/quant-minmax.png) :label:`ch-deploy/quant-minmax` The number of bits and the range of data represented by different data @@ -288,7 +288,7 @@ quantized to represent weights using fewer bits. In addition, using Huffman coding can further reduce the memory cost of the deep neural network. -![Deep Compressionalgorithm](../img/ch08/ch09-deepcomp.png) +![Deep Compressionalgorithm](../img/ch08/deepcomp.png) :label:`ch-deploy/deepcomp` In addition to removing redundant neurons, a dictionary learning-based diff --git a/v1/en_chapters/chapter_model_deployment/model_converter_and_optimizer.md b/v1/en_chapters/chapter_model_deployment/model_converter_and_optimizer.md index 5ce3de2..fa933a1 100644 --- a/v1/en_chapters/chapter_model_deployment/model_converter_and_optimizer.md +++ b/v1/en_chapters/chapter_model_deployment/model_converter_and_optimizer.md @@ -56,7 +56,7 @@ performed (depending on the backend hardware support) once the compilation is complete. However, some optimization operations can only be performed in their entirety during the deployment phase. -![Layered computer storagearchitecture](../img/ch08/ch09-storage.png) +![Layered computer storagearchitecture](../img/ch08/storage.png) :label:`ch-deploy/fusion-storage` ## Operator Fusion @@ -81,7 +81,7 @@ operations on the memory. Furthermore, operator fusion allows some computation to be completed in advance, eliminating redundant or even cyclic redundant computing during forward computation. -![Convolution + Batchnorm operatorfusion](../img/ch08/ch09-conv-bn-fusion.png) +![Convolution + Batchnorm operatorfusion](../img/ch08/conv-bn-fusion.png) :label:`ch-deploy/conv-bn-fusion` To describe the principle of operator fusion, we will use two operators, @@ -174,7 +174,7 @@ type of operators that have the same computational logic but are more suitable for online deployment. In this way, we can reduce the computation workload and compress the model. -![Replacement ofBatchnorm](../img/ch08/ch09-bn-replace.png) +![Replacement ofBatchnorm](../img/ch08/bn-replace.png) :label:`ch-deploy/bn-replace` Figure :numref:`ch-deploy/bn-replace` depicts the replacement of @@ -210,7 +210,7 @@ Common methods of operator reordering include moving cropping operators (e.g., Slice, StrideSlice, and Crop) forward, and reordering Reshape, Transpose, and BinaryOp. -![Reordering ofCrop](../img/ch08/ch09-crop-reorder.png) +![Reordering ofCrop](../img/ch08/crop-reorder.png) :label:`ch-deploy/crop-reorder` Crop is used to cut a part out of the input feature map as the output. diff --git a/v1/en_chapters/chapter_model_deployment/model_inference.md b/v1/en_chapters/chapter_model_deployment/model_inference.md index 98ff81d..23a2938 100644 --- a/v1/en_chapters/chapter_model_deployment/model_inference.md +++ b/v1/en_chapters/chapter_model_deployment/model_inference.md @@ -76,7 +76,7 @@ partitioned, and multiple threads are used to process different data partitions. This allows operators to be computed in parallel, thereby multiplying the operator performance. -![Data partitioning for matrixmultiplication](../img/ch08/ch09-parallel.png) +![Data partitioning for matrixmultiplication](../img/ch08/parallel.png) :label:`ch09_parallel` In Figure :numref:`ch09_parallel`, the matrix in the multiplication can be @@ -144,7 +144,7 @@ Figure :numref:`ch-deploy/register`, NEON register v0 can store 128 bits, which is equal to the capacity of 4 float32, 8 float16, or 16 int8. -![Structure of the NEON register v0 of an ARMv8CPU](../img/ch08/ch09-register.png) +![Structure of the NEON register v0 of an ARMv8CPU](../img/ch08/register.png) :label:`ch-deploy/register` The single instruction multiple data (SIMD) method can be used to @@ -157,7 +157,7 @@ multiple data values in the NEON register at a time. For example, the floating-point values in registers v1 and v2 are added to the value in v0. -![fmla instructioncomputing](../img/ch08/ch09-fmla.png) +![fmla instructioncomputing](../img/ch08/fmla.png) :label:`ch-deploy/fmla` **3) Assembly language optimization** @@ -217,7 +217,7 @@ Figure :numref:`ch-deploy/conv_nhwc` is a diagram of convolution. The input shape is (1, IH, IW, IC), the convolution kernel shape is (OC, KH, KW, IC), and the output shape is (1, OH, OW, OC). -![Generalconvolution](../img/ch08/ch09-conv_nhwc.png) +![Generalconvolution](../img/ch08/conv_nhwc.png) :label:`ch-deploy/conv_nhwc` As shown in Figure @@ -227,7 +227,7 @@ on the right. The number of rows corresponds to the number of OH \* OW outputs. For a row vector, Img2col processes KH \* KW data points of each input channel in sequence, from the first channel to channel IC. -![Img2col on the convolutioninput](../img/ch08/ch09-img2col_input.png) +![Img2col on the convolutioninput](../img/ch08/img2col_input.png) :label:`ch-deploy/img2col_input` As shown in Figure @@ -240,7 +240,7 @@ convolution operation is converted into the multiplication of two matrices. In practice, the data rearrangement of Img2col and GEMM is performed simultaneously to save time. -![Img2col on the convolutionkernel](../img/ch08/ch09-img2col_weight.png) +![Img2col on the convolutionkernel](../img/ch08/img2col_weight.png) :label:`ch-deploy/img2col_weight` **(2) Winograd** @@ -342,7 +342,7 @@ $$\textit{\textbf{Y}}=\textit{\textbf{A}}^{\rm T}(\textit{\textbf{G}}g\textit{\t The logical process of Winograd can be divided into four steps, as shown in Figure :numref:`ch-deploy/winograd`. -![Winogradsteps](../img/ch08/ch09-winograd.png) +![Winogradsteps](../img/ch08/winograd.png) :label:`ch-deploy/winograd` To use Winograd of ***F***(2$\times$``{=html}2, diff --git a/v1/en_chapters/chapter_programming_interface/index.md b/v1/en_chapters/chapter_programming_interface/index.md index 11b7276..6a72305 100644 --- a/v1/en_chapters/chapter_programming_interface/index.md +++ b/v1/en_chapters/chapter_programming_interface/index.md @@ -40,10 +40,10 @@ The chapter aims to achieve the following learning objectives: ```toc :maxdepth: 2 -Overview -Machine_Learning_Workflow -Neural_Network_Programming -Functional_Programming -Bridging_Python_and_C_C++_Functions -Chapter_Summary +development_history +ml_workflow +neural_network_layer +c_python_interaction +ml_programming_paradigm +summary ``` diff --git a/v1/en_chapters/chapter_programming_interface/ml_workflow.md b/v1/en_chapters/chapter_programming_interface/ml_workflow.md index 8fc64f1..6b745b5 100644 --- a/v1/en_chapters/chapter_programming_interface/ml_workflow.md +++ b/v1/en_chapters/chapter_programming_interface/ml_workflow.md @@ -125,5 +125,5 @@ for batch_idx, (data, target) in enumerate(testing_dataloader): # For debugging, you can print logs inside the training or evaluation loop, or use python debugger. ``` -![Workflow within a machine learningsystem](../img/ch03/workflow.pdf) +![Workflow within a machine learningsystem](../img/ch02/img_workflow.svg) :label:`ch03/workflow` diff --git a/v1/en_chapters/chapter_programming_interface/neural_network_layer.md b/v1/en_chapters/chapter_programming_interface/neural_network_layer.md index 34e9412..421717d 100644 --- a/v1/en_chapters/chapter_programming_interface/neural_network_layer.md +++ b/v1/en_chapters/chapter_programming_interface/neural_network_layer.md @@ -32,7 +32,7 @@ connected layer grows substantially --- from n$\times$m during the initial transformation to m$\times$p in the subsequent one.
- +
Fully connected layer illustration
@@ -147,7 +147,7 @@ for inserting/deleting parameters, adding/removing neural network layers, and retrieving neural network model information.
- +
Abstraction technique of neural network base classes
diff --git a/v1/en_chapters/chapter_recommender_system/case_study.md b/v1/en_chapters/chapter_recommender_system/case_study.md index 2f03a44..c9293b2 100644 --- a/v1/en_chapters/chapter_recommender_system/case_study.md +++ b/v1/en_chapters/chapter_recommender_system/case_study.md @@ -112,7 +112,7 @@ synchronization, we'll examine Ekko. Figure architecture where replicas can be synchronized among decentralized parameter servers. -![Example of decentralized synchronization protocols for parameterservers](../img/ch_recommender/p2p_replication.png) +![Example of decentralized synchronization protocols for parameterservers](../img/ch10/ch-recsys/p2p_replication.png) :label:`P2P replication` To execute the peer-to-peer synchronization algorithm, Ekko first @@ -203,7 +203,7 @@ considered high priority; otherwise, it is deemed low priority. The value of *k* is user-defined, and the kth percentile is estimated using an existing algorithm based on historical priority data. -![Application-aware model update scheduler](../img/ch_recommender/update_scheduler.png) +![Application-aware model update scheduler](../img/ch10/ch-recsys/update_scheduler.png) :label:`model update scheduler` ## Online Model State Management @@ -230,7 +230,7 @@ this model is redirected to another model in a healthy state. The corrupted model is then rolled back to a previous healthy state before being reintroduced online. -![Online Model StateManagement](../img/ch_recommender/state_manager.png) +![Online Model StateManagement](../img/ch10/ch-recsys/state_manager.png) :label:`model state manager` [^1]: The update amplitude could either be the gradient itself or the diff --git a/v1/en_chapters/chapter_recommender_system/index.md b/v1/en_chapters/chapter_recommender_system/index.md index ebb6bd9..1029e97 100644 --- a/v1/en_chapters/chapter_recommender_system/index.md +++ b/v1/en_chapters/chapter_recommender_system/index.md @@ -34,12 +34,10 @@ This chapter has the following learning objectives: ```toc :maxdepth: 2 -Overview -System_Components -Recommendation_Pipeline -Model_Update -Supporting_Real-time_Machine_Learning -Chapter_Summary -Further_Reading +system_architecture +multi_stage_recommender_system +model_update +case_study +summary ``` diff --git a/v1/en_chapters/chapter_recommender_system/model_update.md b/v1/en_chapters/chapter_recommender_system/model_update.md index 8270a30..3fda70f 100644 --- a/v1/en_chapters/chapter_recommender_system/model_update.md +++ b/v1/en_chapters/chapter_recommender_system/model_update.md @@ -58,7 +58,7 @@ quality of recommendation. A depiction of this offline model update process can be seen in Figure :numref:`offline update`. -![Offline Process of UpdatingModels](../img/ch_recommender/offline_update.png) +![Offline Process of UpdatingModels](../img/ch10/ch-recsys/offline_update.png) :label:`offline update` To break it down, when a model completes a training period, the diff --git a/v1/en_chapters/chapter_recommender_system/multi_stage_recommender_system.md b/v1/en_chapters/chapter_recommender_system/multi_stage_recommender_system.md index 1b2bbef..85ea932 100644 --- a/v1/en_chapters/chapter_recommender_system/multi_stage_recommender_system.md +++ b/v1/en_chapters/chapter_recommender_system/multi_stage_recommender_system.md @@ -20,7 +20,7 @@ diminished accuracy. On the other hand, using a more complex model may provide more accurate results but deter users due to longer waiting times. -![Example of a multi-stage recommendationpipeline](../img/ch_recommender/recommender_pipeline.png) +![Example of a multi-stage recommendationpipeline](../img/ch10/ch-recsys/recommender_pipeline.png) :label:`recommender pipeline` To mitigate this, contemporary recommender systems typically deploy @@ -63,7 +63,7 @@ each representing a unique user or item. The two-tower model employs a scoring function to evaluate the similarity between user vectors and item vectors. -![Structure of the two-towermodel](../img/ch_recommender/two_tower_model.png) +![Structure of the two-towermodel](../img/ch10/ch-recsys/two_tower_model.png) :label:`two tower model` ### Training @@ -180,7 +180,7 @@ Deep Learning Recommendation Model (DLRM). As depicted in Figure DLRM consists of embedding tables, multi-layer perceptrons (MLPs) that include two layers, and an interaction layer.[^2] -![Structure of DLRM](../img/ch_recommender/dlrm_model.png) +![Structure of DLRM](../img/ch10/ch-recsys/dlrm_model.png) :label:`dlrm model` Similar to the two-tower model, the DLRM initially uses embedding tables @@ -205,7 +205,7 @@ the input for the top MLP. After further processing by the top MLP, the final output score reflects the probability of a user clicking on the item. -![Interaction principlediagram](../img/ch_recommender/interaction.png) +![Interaction principlediagram](../img/ch10/ch-recsys/interaction.png) :label:`interaction` ### Training Process diff --git a/v1/en_chapters/chapter_recommender_system/system_architecture.md b/v1/en_chapters/chapter_recommender_system/system_architecture.md index 3244ce5..ebd6ddf 100644 --- a/v1/en_chapters/chapter_recommender_system/system_architecture.md +++ b/v1/en_chapters/chapter_recommender_system/system_architecture.md @@ -26,7 +26,7 @@ Inference servers handle user requests, procure the necessary model parameters from parameter servers based on these requests, and calculate the recommendation outcomes. -![Architecture of a recommendersystem](../img/ch_recommender/recommender_system.png) +![Architecture of a recommendersystem](../img/ch10/ch-recsys/ch10-recommendation-systems.png) :label:`recommender systems` # System Components @@ -87,7 +87,7 @@ store. When the training or inference module needs to access a specific user's features, all necessary features can be retrieved from the feature store using just the user ID. -![Example of a featurestore](../img/ch_recommender/feature_store.png) +![Example of a featurestore](../img/ch10/ch-recsys/feature_store.png) :label:`feature store` One significant advantage of utilizing feature stores is the potential @@ -142,7 +142,7 @@ space. The structure of an embedding table in a recommendation model bears resemblance to its counterpart in a natural language processing (NLP) model, though there are subtle distinctions. -![Structure of a recommendation model](../img/ch_recommender/recommendation_model.png) +![Structure of a recommendation model](../img/ch10/ch-recsys/ch10-recommendation-models.png) :label:`recommendation models` In NLP models, the majority of parameters are found within deep neural @@ -197,7 +197,7 @@ offered by the parameter server architecture greatly improves the efficiency of storage and computation resource management in recommendation systems. -![Role of parameter servers in a recommender system](../img/ch_recommender/parameter_server_in_recommendation.png) +![Role of parameter servers in a recommender system](../img/ch10/ch-recsys/parameter_server_in_recommendation.png) :label:`parameter server in recommendation` The parameter servers in a recommender system have a dual role. They diff --git a/v1/en_chapters/chapter_reinforcement_learning/index.md b/v1/en_chapters/chapter_reinforcement_learning/index.md index 44ff5b6..5b91d6b 100644 --- a/v1/en_chapters/chapter_reinforcement_learning/index.md +++ b/v1/en_chapters/chapter_reinforcement_learning/index.md @@ -9,11 +9,9 @@ training intelligent systems to maximize cumulative reward over time. ```toc :maxdepth: 2 -Overview -Introduction_to_Reinforcement_Learning -Single-Node_Reinforcement_Learning_System -Distributed_Reinforcement_Learning_System -Multi-agent_Reinforcement_Learning -Multi-agent_Reinforcement_Learning_System -Chapter_Summary +rl_introduction +single_node_rl +marl +marl_sys +summary ``` diff --git a/v1/en_chapters/chapter_reinforcement_learning/marl.md b/v1/en_chapters/chapter_reinforcement_learning/marl.md index 571d72b..0eb4d3f 100644 --- a/v1/en_chapters/chapter_reinforcement_learning/marl.md +++ b/v1/en_chapters/chapter_reinforcement_learning/marl.md @@ -25,7 +25,7 @@ observations are the environment states. However, this is the least possible in the real world. In practice, agents usually have different observations on the environment. -![Two possible multiagent reinforcement learning frameworks: (a)Synchronous multiagent decision-making; (b) Asynchronous multiagentdecision-making](../img/ch11/ch11-marl.pdf) +![Two possible multiagent reinforcement learning frameworks: (a)Synchronous multiagent decision-making; (b) Asynchronous multiagentdecision-making](../img/ch12/ch12-marl.png) :label:`ch011/ch11-marl` ## Multi-agent RL @@ -120,7 +120,7 @@ converge to the objective we expect. Due to the possible existence of such a cycle, we need training methods that are more complex and methods that are designed for multiagent learning to achieve our objective. -![Self-playalgorithm](../img/ch11/ch11-marl-sp.png) +![Self-playalgorithm](../img/ch12/ch12-marl-sp.png) :label:`ch011/ch11-marl-sp` Generally, multiagent reinforcement learning is more complex than @@ -140,7 +140,7 @@ an optimal strategy based on its opponent's historical average strategies, and vice versa. In this manner, players can converge to Nash equilibrium strategy in games like rock-paper-scissors. -![Fictitious self-playalgorithm](../img/ch11/ch11-marl-fsp.pdf) +![Fictitious self-playalgorithm](../img/ch12/ch12-marl-fsp.png) :label:`ch011/ch11-marl-fsp` [^1]: Assume that the agents use the same reward discount factor. diff --git a/v1/en_chapters/chapter_reinforcement_learning/marl_sys.md b/v1/en_chapters/chapter_reinforcement_learning/marl_sys.md index 9bfa20e..e94e79a 100644 --- a/v1/en_chapters/chapter_reinforcement_learning/marl_sys.md +++ b/v1/en_chapters/chapter_reinforcement_learning/marl_sys.md @@ -36,7 +36,7 @@ type of method relies on a distributed system to implement multi-agent training and gaming, reflecting the dependency of multi-agent reinforcement learning on distributed computing. -![Multi-agent reinforcement learning training in the form of aleague](../img/ch11/ch11-marl-train.pdf) +![Multi-agent reinforcement learning training in the form of aleague](../img/ch12/ch12-marl-train.svg) :label:`ch011/ch11-marl-train` Now, let's look at the difficulties involved in building a multi-agent @@ -195,5 +195,5 @@ training. While this example describes a distributed multi-agent system in general terms, there may be many different designs for different game types and algorithm structures in real-world applications. -![Distributed multi-agent reinforcement learningsystem](../img/ch11/ch11-marl-sys.png) +![Distributed multi-agent reinforcement learningsystem](../img/ch12/ch12-marl-sys.png) :label:`ch011/ch11-marl-sys` diff --git a/v1/en_chapters/chapter_reinforcement_learning/rl_introduction.md b/v1/en_chapters/chapter_reinforcement_learning/rl_introduction.md index 24a8e7f..2258b9d 100644 --- a/v1/en_chapters/chapter_reinforcement_learning/rl_introduction.md +++ b/v1/en_chapters/chapter_reinforcement_learning/rl_introduction.md @@ -42,7 +42,7 @@ Figure :numref:`ch011/ch11-rl` shows the abstract process, which is the most common model description of reinforcement learning in the literature. -![Framework of reinforcementlearning](../img/ch11/ch11-rl.pdf) +![Framework of reinforcementlearning](../img/ch12/ch12-rl.png) :label:`ch011/ch11-rl` Take video gaming as an example. A gamer needs to gradually become diff --git a/v1/en_chapters/chapter_reinforcement_learning/single_node_rl.md b/v1/en_chapters/chapter_reinforcement_learning/single_node_rl.md index 9fbd513..1dcd277 100644 --- a/v1/en_chapters/chapter_reinforcement_learning/single_node_rl.md +++ b/v1/en_chapters/chapter_reinforcement_learning/single_node_rl.md @@ -67,7 +67,7 @@ discrete, continuous, or categorical. The three types of adapters are collectively referred to as adapters in Figure :numref:`ch011/ch11-rlzoo`. -![Reinforcement learning system used in the RLzoo algorithmlibrary](../img/ch11/ch11-rlzoo.pdf) +![Reinforcement learning system used in the RLzoo algorithmlibrary](../img/ch12/ch12-rlzoo.png) :label:`ch011/ch11-rlzoo` The policy networks and value networks constitute the core learning diff --git a/v1/en_chapters/chapter_rl_sys/index.md b/v1/en_chapters/chapter_rl_sys/index.md index a452c90..a044040 100644 --- a/v1/en_chapters/chapter_rl_sys/index.md +++ b/v1/en_chapters/chapter_rl_sys/index.md @@ -13,10 +13,10 @@ chapter are as follows: ```toc :maxdepth: 2 -Overview_of_Robotic_Systems -Robot_Operating_System -Case_Study -Modern_Robot_Learning -Chapter_Summary +rl_sys_intro +ros +ros_code_ex +robot_learning +summary ``` diff --git a/v1/en_chapters/chapter_rl_sys/rl_sys_intro.md b/v1/en_chapters/chapter_rl_sys/rl_sys_intro.md index a59c1cb..53d7135 100644 --- a/v1/en_chapters/chapter_rl_sys/rl_sys_intro.md +++ b/v1/en_chapters/chapter_rl_sys/rl_sys_intro.md @@ -42,7 +42,7 @@ decision strategy can be trained through re-parameterization. We will introduce the perception, planning, and control systems in the following subsections. -![Automatic driving framework based on imitation learning](../img/ch17/idm.png) +![Automatic driving framework based on imitation learning](../img/ch13/idm.png) :label:`ch17/ch17-learning_decision_module` ## Perception System @@ -100,7 +100,7 @@ frameworks have been proposed. TartanVO, which outperforms traditional geometry-based methods, is the first learning-based VO model that can be generalized to multiple datasets and real-world scenarios. -![Main system components ofORB-SLAM3](../img/ch17/orbslam3.png) +![Main system components ofORB-SLAM3](../img/ch13/orbslam3.png) :label:`ch17/ch17-orbslam3` ## Planning System @@ -136,7 +136,7 @@ Decision Process (POMDP) model for autonomous driving based on deep RL, covering important components such as the environment, reward, and agent. -![POMDP model for deep RL--based autonomousdriving ](../img/ch17/rl_ad.png) +![POMDP model for deep RL--based autonomousdriving ](../img/ch13/rl_ad.png) :label:`ch17/ch17-rl_ad` ## Control System @@ -188,7 +188,7 @@ a safe learning control system. Lyapunov functions can effectively evaluate the stability of nonlinear dynamical systems. Recently, neural Lyapunov has been proposed to take safety into account. -![Safe learning control system where data is used to update controlstrategies or safetyfilters](../img/ch17/safe_learning_control.png) +![Safe learning control system where data is used to update controlstrategies or safetyfilters](../img/ch13/safe_learning_control.png) :label:`ch17/ch17-safe_learning_control` ## Robot Safety diff --git a/v1/en_chapters/chapter_rl_sys/robot_learning.md b/v1/en_chapters/chapter_rl_sys/robot_learning.md index 0839f7e..de5c69a 100644 --- a/v1/en_chapters/chapter_rl_sys/robot_learning.md +++ b/v1/en_chapters/chapter_rl_sys/robot_learning.md @@ -19,7 +19,7 @@ variation for a robot to expect to have an accurate model of its environment, the objects in it, or the skills required to manipulate them. -![An Overview of Common Frameworks for RobotLearning.](../img/ch13/framework.pdf) +![An Overview of Common Frameworks for RobotLearning.](../img/ch13/robot_learning_overview.png) :label:`robot-framework` ## Robot Interaction Environments @@ -94,7 +94,7 @@ crucial for achieving successful transfer of learned policies from simulation to reality. ![Robot manipulation environments in real -world [@geng2022end].](../img/ch13/realworld.pdf) +world [@geng2022end].](../img/ch13/real-world.png) ### Hardware Considerations: :label:`hardware-considerations` @@ -237,7 +237,7 @@ an action in a given state. **Affordance Learning:** ![Affordance visualization results in robot manipulation -tasks [@geng2022end].](../img/ch13/affordance.pdf) +tasks [@geng2022end].](../img/ch13/affordance.png) Affordance learning focuses on understanding the action possibilities that the environment offers to a diff --git a/v1/en_chapters/chapter_rl_sys/ros.md b/v1/en_chapters/chapter_rl_sys/ros.md index 0ac04d2..b06e1c1 100644 --- a/v1/en_chapters/chapter_rl_sys/ros.md +++ b/v1/en_chapters/chapter_rl_sys/ros.md @@ -58,7 +58,7 @@ performance. The communication system of ROS 2 is based on the data distribution service (DDS), as shown in Figure :numref:`ch17/ch17-ROS2_arch`. -![Overview of ROS/ROS 2architecture ](../img/ch17/ROS2_arch.png) +![Overview of ROS/ROS 2architecture ](../img/ch13/ROS2_arch.png) :label:`ch17/ch17-ROS2_arch` ROS 2 relies on combining workspaces using the shell environment. @@ -96,7 +96,7 @@ summarized as follows: 3. Before a node goes offline, it also broadcasts the offline information to other nodes. -![Robotic system consisting of many nodes working inconcert](../img/ch17/ros2_graph.png) +![Robotic system consisting of many nodes working inconcert](../img/ch13/ros2_graph.png) :label:`ch17/ch17-ROS2_graph` ## ROS 2 Topics @@ -114,7 +114,7 @@ windows within rqt. Although we can run such tools in a traditional standalone manner, rqt makes it easier to manage the various types of windows on the screen simultaneously. -![A node can publish data and subscribe to any number of topicssimultaneously.](../img/ch17/ros2_topics.png) +![A node can publish data and subscribe to any number of topicssimultaneously.](../img/ch13/ros2_topics.png) :label:`ch17/ch17-ROS2_topics` ## ROS 2 Services @@ -131,7 +131,7 @@ providing a desired service and the service processes the request and generates a response, as shown in Figure :numref:`ch17/ch17-ROS2_services`. -![ROS 2service](../img/ch17/ros2_services.png) +![ROS 2service](../img/ch13/ros2_services.png) :label:`ch17/ch17-ROS2_services` ## ROS 2 Parameters @@ -158,7 +158,7 @@ an action goal can tell a robot to head for a position. The robot can send updates (i.e., feedback) while it navigates a path to the position, and then send a result message when it arrives at its destination. -![ROS 2 action](../img/ch17/ros2_actions.png) +![ROS 2 action](../img/ch13/ros2_actions.png) :label:`ch17/ch17-ROS2_actions` [^1]: https://docs.ros.org/en/foxy/Tutorials/Understanding-ROS2-Nodes.html diff --git a/v1/en_chapters/index.md b/v1/en_chapters/index.md index 1b9b862..e31f281 100644 --- a/v1/en_chapters/index.md +++ b/v1/en_chapters/index.md @@ -8,15 +8,16 @@ Machine Learning Systems: Design and Implementation (1st Edition) ```toc :maxdepth: 2 -:numbered: chapter_preface/index + +# Fundamentals chapter_introduction/index chapter_programming_interface/index chapter_computational_graph/index -chapter_preface_advanced/index - +# Part I Framework Design +[Overview](chapter_preface_advanced/index) chapter_frontend_and_ir/index chapter_backend_and_runtime/index chapter_accelerator/index @@ -24,18 +25,15 @@ chapter_data_processing/index chapter_model_deployment/index chapter_distributed_training/index -chapter_preface_extension/index - +# Part II Application Scenarios +[Overview](chapter_preface_extension/index) chapter_recommender_system/index chapter_federated_learning/index chapter_reinforcement_learning/index chapter_explainable_AI/index chapter_rl_sys/index -``` - -```toc -:maxdepth: 1 - +# Appendix appendix_machine_learning_introduction/index ``` + diff --git a/v1/img/ch07/7.5/distribute.png b/v1/img/ch07/7.5/distribute.png new file mode 100644 index 0000000000000000000000000000000000000000..e7ea450aa23dd7563a04ac57d84479b71c77b507 GIT binary patch literal 74646 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

B-3eu8aQuY6_R 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 i0#oSMK>rsMUcnQ=}4 literal 0 HcmV?d00001