From 6c9673a6596793d0f9da1d02c3074d0338ddbc61 Mon Sep 17 00:00:00 2001 From: anyin233 <35858233+anyin233@users.noreply.github.com> Date: Wed, 11 Mar 2026 16:17:37 +0000 Subject: [PATCH] build: migrate docs build and deploy to mdbook (#490) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * build: add mdbook support for zh chapters Add mdBook configuration rooted at zh_chapters, generate and commit SUMMARY.md, rewrite d2l-specific directives through a Python preprocessor, refresh chapter resource symlinks from the build scripts, and ignore local build-only links and helper directories. * feat: add raw HTML inline and frontpage layout support for mdbook preprocessor Co-Authored-By: Claude Opus 4.6 * feat: add dark mode image background for mdbook dark themes Co-Authored-By: Claude Opus 4.6 * fix: add resource symlinks and repo root static fallback to mdbook build Co-Authored-By: Claude Opus 4.6 * feat: add BibTeX citation support with inline links and bibliography Parse mlsys.bib to generate author-year inline citations linked to per-page bibliography sections. Missing bib keys degrade gracefully to plain text placeholders. Co-Authored-By: Claude Opus 4.6 * refactor: switch citation display to footnote style Use numbered superscript references [1] [2] inline with an ordered list bibliography at page bottom. Each entry has a back-link (↩) to the citation site. Co-Authored-By: Claude Opus 4.6 * fix: strip LaTeX escapes outside math mode in mdbook preprocessor Remove \_, \%, \#, \& escapes from text outside $...$ math spans while preserving them inside math mode for MathJax compatibility. Co-Authored-By: Claude Opus 4.6 * style: set frontpage author grid to 6 columns and widen main content area Co-Authored-By: Claude Opus 4.6 * fix: group mdbook toc by part titles * fix: enable inline math rendering in mdbook * build: migrate docs publishing to mdbook Move the English root site to mdBook, keep the Chinese site as a sub-book, and update CI/deploy to publish .mdbook outputs to docs/ and docs/cn/. Also add regression coverage for placeholder skipping, publish-tree assembly, and shared resource setup. * ci: use official pages deployment workflow Switch the docs deployment workflow to the official GitHub Pages actions flow and verify it uses Pages action outputs for the deployment URL. * feat: add homepage language switch links Inject a homepage-only language switch into the mdBook frontpage wrapper so the English homepage links to the Chinese homepage and the Chinese homepage links back to the English homepage. * fix: correct english homepage frontpage Add an English-specific frontpage template so the default homepage no longer falls back to the Chinese frontpage, and clear homepage image backgrounds in the frontpage wrapper CSS. * fix: align english homepage author grid Top-align the English homepage author cards, enlarge the row gap, and normalize avatar sizing so author portraits line up consistently. * fix: restore dark mode body image backgrounds Apply light gray backgrounds to body images in dark themes for both English and Chinese mdBook themes while explicitly excluding homepage frontpage images. * fix: restyle homepage language switch button Move the homepage language switch below the GitHub star button and restyle it to match the same button family on both the English and Chinese homepages. * fix: center homepage content container Align the English and Chinese homepage frontpage wrapper with the main content container so homepage content is centered like normal body content. * fix: stack english homepage footer copy Keep the English homepage contributor and errata footer lines in normal block flow so each sentence stays on its own line instead of being laid out as author-grid columns. * fix: widen centered homepage container Keep the homepage frontpage wrapper centered while ensuring it uses at least 80% of the available content area, without changing normal body page layout. * fix: widen homepage main content area Apply a homepage-only override so mdbook-content > main uses at least 80% of the available content width while keeping normal body pages on the default layout. * ci: use peaceiris action for mdbook Replace manual mdBook installation in CI and Pages workflows with peaceiris/actions-mdbook@v2 and keep a regression test to ensure the action stays in use. * fix: reduce homepage main width floor Lower the homepage-only mdbook-content > main minimum width from 80% to 65% while leaving normal body pages unchanged. * build: switch math rendering to mdbook-katex Use mdbook-katex in pre-render mode for both books, pin mdBook to a compatible version, update build scripts and workflows, and replace the old MathJax regression tests with KaTeX coverage. * Revert "build: switch math rendering to mdbook-katex" This reverts commit b9cf38a5d1e477a57fe00dc5f721106440e28ca9. * build: switch math rendering from MathJax to mdbook-typst-math * ci: deploy docs to openmlsys.github.io repo * fix: convert pandoc tables to GFM pipe tables for mdbook * feat: convert :eqlabel:/:eqref: to MathJax \tag/\label/\eqref - Add process_equation_labels() to inject \tag{n}\label{name} into preceding $$ equations, replacing :eqlabel: directives - Change :eqref: conversion from backtick code to $\eqref{name}$ for clickable cross-references - Add TeX.equationNumbers.autoNumber:"none" to MathJax config to prevent conflicts with manual \tag numbering - Add tests for single-line, multi-line, and sequential numbering Co-Authored-By: Claude Opus 4.6 * ci: cache mdbook-typst-math binary in workflows * feat: add LaTeX-to-Typst math converter with eqref/tag support * feat: integrate LaTeX-to-Typst conversion into zh preprocessor * fix: strip LaTeX escapes only outside math spans and code blocks * fix: load references/*.bib so all citations render correctly * fix: skip citations with no bib entry instead of rendering raw keys * ci: remove redundant CI workflow, keep only deploy workflow * ci: Add CI workflow for testing and building mdBook * ci: remove concurrency settings from update_docs.yml Removed concurrency settings from the update_docs workflow. --------- Co-authored-by: Claude Opus 4.6 --- .github/workflows/main.yml | 78 +- .github/workflows/update_docs.yml | 66 +- .gitignore | 17 + book.toml | 19 + books/zh/book.toml | 19 + books/zh/theme/dark-mode-images.css | 16 + books/zh/theme/typst.css | 16 + build_html.sh | 7 +- build_html_zh.sh | 7 +- build_mdbook.sh | 27 + build_mdbook_zh.sh | 29 + en_chapters/SUMMARY.md | 3 + en_chapters/frontpage.html | 507 +++++++ en_chapters/img | 1 - en_chapters/references | 1 - en_chapters/static | 1 - static/frontpage.html | 2 +- tests/test_assemble_docs_publish_tree.py | 87 ++ tests/test_dark_mode_images_css.py | 30 + tests/test_ensure_book_resources.py | 55 + tests/test_ensure_mdbook_typst_math.py | 134 ++ tests/test_mdbook_typst_math.py | 38 + tests/test_prepare_mdbook.py | 237 +++ tests/test_prepare_mdbook_zh.py | 266 ++++ tests/test_update_docs_workflow.py | 29 + theme/dark-mode-images.css | 16 + theme/typst.css | 16 + tools/assemble_docs_publish_tree.py | 97 ++ tools/ensure_book_resources.py | 60 + tools/ensure_mdbook_typst_math.py | 132 ++ tools/latex_to_typst.py | 614 ++++++++ tools/mdbook_preprocessor.py | 66 + tools/mdbook_zh_preprocessor.py | 68 + tools/prepare_mdbook.py | 790 ++++++++++ tools/prepare_mdbook_zh.py | 75 + zh_chapters/SUMMARY.md | 110 ++ .../intermediate_representation.md | 14 +- .../model_converter_and_optimizer.md | 12 +- .../chapter_reinforcement_learning/index.md | 1 - zh_chapters/img | 1 - zh_chapters/index.md | 21 +- zh_chapters/mlsys.bib | 1308 +---------------- zh_chapters/references | 1 - zh_chapters/static | 1 - 44 files changed, 3654 insertions(+), 1441 deletions(-) create mode 100644 book.toml create mode 100644 books/zh/book.toml create mode 100644 books/zh/theme/dark-mode-images.css create mode 100644 books/zh/theme/typst.css create mode 100644 build_mdbook.sh create mode 100755 build_mdbook_zh.sh create mode 100644 en_chapters/SUMMARY.md create mode 100644 en_chapters/frontpage.html delete mode 120000 en_chapters/img delete mode 120000 en_chapters/references delete mode 120000 en_chapters/static create mode 100644 tests/test_assemble_docs_publish_tree.py create mode 100644 tests/test_dark_mode_images_css.py create mode 100644 tests/test_ensure_book_resources.py create mode 100644 tests/test_ensure_mdbook_typst_math.py create mode 100644 tests/test_mdbook_typst_math.py create mode 100644 tests/test_prepare_mdbook.py create mode 100644 tests/test_prepare_mdbook_zh.py create mode 100644 tests/test_update_docs_workflow.py create mode 100644 theme/dark-mode-images.css create mode 100644 theme/typst.css create mode 100644 tools/assemble_docs_publish_tree.py create mode 100644 tools/ensure_book_resources.py create mode 100644 tools/ensure_mdbook_typst_math.py create mode 100644 tools/latex_to_typst.py create mode 100644 tools/mdbook_preprocessor.py create mode 100644 tools/mdbook_zh_preprocessor.py create mode 100644 tools/prepare_mdbook.py create mode 100644 tools/prepare_mdbook_zh.py create mode 100644 zh_chapters/SUMMARY.md delete mode 120000 zh_chapters/img mode change 100644 => 120000 zh_chapters/mlsys.bib delete mode 120000 zh_chapters/references delete mode 120000 zh_chapters/static diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8b79f0f..0a8621e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,8 +6,8 @@ on: workflow_dispatch: jobs: - build-en: - name: Build (English) + test: + name: Tests runs-on: ubuntu-22.04 steps: @@ -17,62 +17,30 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.10' - cache: 'pip' - - name: Install pandoc - run: | - wget -q https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-amd64.deb - sudo dpkg -i pandoc-2.19.2-1-amd64.deb - - - name: Install d2lbook - run: | - git clone https://github.com/openmlsys/d2l-book.git - cd d2l-book - # Fix Python 3.10+ incompatibility: bibtex<2.0.0 depends on oset which - # uses collections.MutableSet removed in Python 3.10. - sed -i "s/'sphinxcontrib-bibtex<2.0.0'/'sphinxcontrib-bibtex>=2.5.0'/" setup.py - python3 -m pip install . - - - name: Install Python dependencies - run: python3 -m pip install -r requirements.txt - - - name: Build English HTML - run: bash build_html.sh - - build-zh: - name: Build (Chinese) - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python 3.10 - uses: actions/setup-python@v5 + - name: Setup mdBook + uses: peaceiris/actions-mdbook@v2 with: - python-version: '3.10' - cache: 'pip' + mdbook-version: 'latest' - - name: Install pandoc + - name: Cache mdbook-typst-math binary + uses: actions/cache@v4 + with: + path: .mdbook-bin + key: mdbook-typst-math-v0.3.0-linux-x86_64 + + - name: Run mdBook regression tests run: | - wget -q https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-amd64.deb - sudo dpkg -i pandoc-2.19.2-1-amd64.deb + python3 -m unittest discover -s tests -p 'test_prepare_mdbook.py' + 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_mdbook_typst_math.py' + python3 -m unittest discover -s tests -p 'test_ensure_mdbook_typst_math.py' + python3 -m unittest discover -s tests -p 'test_update_docs_workflow.py' - - name: Install d2lbook - run: | - git clone https://github.com/openmlsys/d2l-book.git - cd d2l-book - sed -i "s/'sphinxcontrib-bibtex<2.0.0'/'sphinxcontrib-bibtex>=2.5.0'/" setup.py - python3 -m pip install . + - name: Build English HTML with mdBook + run: bash build_mdbook.sh - - name: Install Python dependencies - run: python3 -m pip install -r requirements.txt - - - name: Build Chinese HTML - run: bash build_html_zh.sh - - build: - name: build - needs: [build-en, build-zh] - runs-on: ubuntu-22.04 - steps: - - run: echo "All builds passed" + - name: Build Chinese HTML with mdBook + run: bash build_mdbook_zh.sh diff --git a/.github/workflows/update_docs.yml b/.github/workflows/update_docs.yml index ac9694a..75a7810 100644 --- a/.github/workflows/update_docs.yml +++ b/.github/workflows/update_docs.yml @@ -16,47 +16,53 @@ jobs: uses: actions/setup-python@v5 with: python-version: '3.10' - cache: 'pip' - - name: Install pandoc + - name: Cache mdbook-typst-math binary + uses: actions/cache@v4 + with: + path: .mdbook-bin + key: mdbook-typst-math-v0.3.0-linux-x86_64 + + - name: Setup mdBook + uses: peaceiris/actions-mdbook@v2 + with: + mdbook-version: 'latest' + + - name: Run mdBook regression tests run: | - wget -q https://github.com/jgm/pandoc/releases/download/2.19.2/pandoc-2.19.2-1-amd64.deb - sudo dpkg -i pandoc-2.19.2-1-amd64.deb + python3 -m unittest discover -s tests -p 'test_prepare_mdbook.py' + 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_mdbook_typst_math.py' + python3 -m unittest discover -s tests -p 'test_ensure_mdbook_typst_math.py' - - name: Install d2lbook - run: | - git clone https://github.com/openmlsys/d2l-book.git - cd d2l-book - # Fix Python 3.10+ incompatibility: bibtex<2.0.0 depends on oset which - # uses collections.MutableSet removed in Python 3.10. - sed -i "s/'sphinxcontrib-bibtex<2.0.0'/'sphinxcontrib-bibtex>=2.5.0'/" setup.py - python3 -m pip install . + - name: Build English HTML with mdBook + run: bash build_mdbook.sh - - name: Install Python dependencies - run: python3 -m pip install -r requirements.txt sphinx-mathjax-offline + - name: Build Chinese HTML with mdBook + run: bash build_mdbook_zh.sh - - name: Build English HTML - run: bash build_html.sh - - - name: Build Chinese HTML - run: bash build_html_zh.sh - - - name: Deploy to GitHub Pages + - name: Deploy to openmlsys.github.io env: DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }} run: | git clone https://x-access-token:${DEPLOY_TOKEN}@github.com/openmlsys/openmlsys.github.io.git - # English → root (default language) - cp -r en_chapters/_build/html/* openmlsys.github.io/docs/ - - # Chinese → /cn/ subdirectory - mkdir -p openmlsys.github.io/docs/cn - cp -r zh_chapters/_build/html/* openmlsys.github.io/docs/cn/ + python3 tools/assemble_docs_publish_tree.py \ + --destination-root openmlsys.github.io \ + --docs-subdir docs \ + --en-source .mdbook/book \ + --zh-source .mdbook-zh/book cd openmlsys.github.io git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add . - git commit -m "deploy: update docs (en+zh) from openmlsys-zh@${{ github.sha }}" || echo "No changes to commit" - git push + git add docs + + if git diff --cached --quiet; then + echo "No changes to commit" + else + git commit -m "deploy: update docs from ${GITHUB_REPOSITORY}@${GITHUB_SHA}" + git push + fi diff --git a/.gitignore b/.gitignore index 2fddff0..9647397 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,20 @@ test*.md run.sh .idea env +.mdbook/ +.mdbook-zh/ +.mdbook-zh-test/ +.mdbook-bin/ +task_plan.md +findings.md +progress.md +d2l-book/ +docs/ +en_chapters/img +en_chapters/references +en_chapters/static +en_chapters/mlsys.bib +zh_chapters/img +zh_chapters/references +zh_chapters/static +zh_chapters/mlsys.bib diff --git a/book.toml b/book.toml new file mode 100644 index 0000000..d5385d1 --- /dev/null +++ b/book.toml @@ -0,0 +1,19 @@ +[book] +authors = ["OpenMLSys Contributors"] +language = "en" +src = "en_chapters" +title = "Machine Learning Systems: Design and Implementation" + +[build] +build-dir = ".mdbook/book" +create-missing = false + +[preprocessor.openmlsys] +command = "python3 tools/mdbook_preprocessor.py" + +[preprocessor.typst-math] + +[output.html] +git-repository-url = "https://github.com/openmlsys/openmlsys-zh" +preferred-dark-theme = "navy" +additional-css = ["theme/dark-mode-images.css", "theme/typst.css"] diff --git a/books/zh/book.toml b/books/zh/book.toml new file mode 100644 index 0000000..7420cc2 --- /dev/null +++ b/books/zh/book.toml @@ -0,0 +1,19 @@ +[book] +authors = ["OpenMLSys Contributors"] +language = "zh-CN" +src = "../../zh_chapters" +title = "机器学习系统:设计和实现" + +[build] +build-dir = "../../.mdbook-zh/book" +create-missing = false + +[preprocessor.openmlsys-zh] +command = "python3 ../../tools/mdbook_zh_preprocessor.py" + +[preprocessor.typst-math] + +[output.html] +git-repository-url = "https://github.com/openmlsys/openmlsys-zh" +preferred-dark-theme = "navy" +additional-css = ["theme/dark-mode-images.css", "theme/typst.css"] diff --git a/books/zh/theme/dark-mode-images.css b/books/zh/theme/dark-mode-images.css new file mode 100644 index 0000000..c5805c1 --- /dev/null +++ b/books/zh/theme/dark-mode-images.css @@ -0,0 +1,16 @@ +/* 暗色模式下仅为正文图片添加浅灰色背景,提高透明背景图片的可读性 */ +.navy .content main img, +.coal .content main img, +.ayu .content main img { + background-color: #e8e8e8; + border-radius: 4px; + padding: 8px; +} + +/* 首页 frontpage 图片保持透明,不添加正文图像底色。 */ +.navy .openmlsys-frontpage img, +.coal .openmlsys-frontpage img, +.ayu .openmlsys-frontpage img { + background-color: transparent !important; + padding: 0 !important; +} diff --git a/books/zh/theme/typst.css b/books/zh/theme/typst.css new file mode 100644 index 0000000..1929751 --- /dev/null +++ b/books/zh/theme/typst.css @@ -0,0 +1,16 @@ +.typst-inline { + display: inline-flex; + vertical-align: -0.2em; +} + +.typst-display { + display: flex; + justify-content: center; + margin: 1rem 0; + overflow-x: auto; +} + +.typst-doc { + color: var(--fg); + max-width: 100%; +} diff --git a/build_html.sh b/build_html.sh index b052657..904791c 100644 --- a/build_html.sh +++ b/build_html.sh @@ -10,12 +10,7 @@ set -e ROOT="$(cd "$(dirname "$0")" && pwd)" # ── Create resource symlinks ────────────────────────────────────────────────── -for target in img references static mlsys.bib; do - link="$ROOT/en_chapters/$target" - if [ ! -e "$link" ]; then - ln -sf "$ROOT/$target" "$link" - fi -done +python3 "$ROOT/tools/ensure_book_resources.py" --chapter-dir "$ROOT/en_chapters" # ── Build ───────────────────────────────────────────────────────────────────── cd "$ROOT/en_chapters" diff --git a/build_html_zh.sh b/build_html_zh.sh index 5d9ec90..ccefd76 100755 --- a/build_html_zh.sh +++ b/build_html_zh.sh @@ -10,12 +10,7 @@ set -e ROOT="$(cd "$(dirname "$0")" && pwd)" # ── Create resource symlinks ────────────────────────────────────────────────── -for target in img references static mlsys.bib; do - link="$ROOT/zh_chapters/$target" - if [ ! -e "$link" ]; then - ln -sf "$ROOT/$target" "$link" - fi -done +python3 "$ROOT/tools/ensure_book_resources.py" --chapter-dir "$ROOT/zh_chapters" # ── Build ───────────────────────────────────────────────────────────────────── cd "$ROOT/zh_chapters" diff --git a/build_mdbook.sh b/build_mdbook.sh new file mode 100644 index 0000000..2062af1 --- /dev/null +++ b/build_mdbook.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PYTHON_BIN="$(command -v python3 || command -v python || true)" + +if [[ -z "${PYTHON_BIN}" ]]; then + echo "Python is required to prepare the mdBook staging tree." >&2 + exit 1 +fi + +if ! command -v mdbook >/dev/null 2>&1; then + echo "mdbook is not installed. Install it first, for example with: cargo install mdbook" >&2 + exit 1 +fi + +MDBOOK_TYPST_MATH_BIN_DIR="${ROOT}/.mdbook-bin" +"${PYTHON_BIN}" "${ROOT}/tools/ensure_mdbook_typst_math.py" --output-dir "${MDBOOK_TYPST_MATH_BIN_DIR}" >/dev/null +export PATH="${MDBOOK_TYPST_MATH_BIN_DIR}:${PATH}" + +"${PYTHON_BIN}" "${ROOT}/tools/ensure_book_resources.py" --chapter-dir "${ROOT}/en_chapters" +"${PYTHON_BIN}" "${ROOT}/tools/prepare_mdbook.py" \ + --source "${ROOT}/en_chapters" \ + --summary-output "${ROOT}/en_chapters/SUMMARY.md" \ + --placeholder-prefix "[TODO: src = zh_chapters/" + +mdbook build "${ROOT}" diff --git a/build_mdbook_zh.sh b/build_mdbook_zh.sh new file mode 100755 index 0000000..06486f8 --- /dev/null +++ b/build_mdbook_zh.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PYTHON_BIN="$(command -v python3 || command -v python || true)" + +if [[ -z "${PYTHON_BIN}" ]]; then + echo "Python is required to prepare the mdBook staging tree." >&2 + exit 1 +fi + +if ! command -v mdbook >/dev/null 2>&1; then + echo "mdbook is not installed. Install it first, for example with: cargo install mdbook" >&2 + exit 1 +fi + +MDBOOK_TYPST_MATH_BIN_DIR="${ROOT}/.mdbook-bin" +"${PYTHON_BIN}" "${ROOT}/tools/ensure_mdbook_typst_math.py" --output-dir "${MDBOOK_TYPST_MATH_BIN_DIR}" >/dev/null +export PATH="${MDBOOK_TYPST_MATH_BIN_DIR}:${PATH}" + +# ── Create resource links ───────────────────────────────────────────────────── +"${PYTHON_BIN}" "${ROOT}/tools/ensure_book_resources.py" --chapter-dir "${ROOT}/zh_chapters" + +# ── Build ───────────────────────────────────────────────────────────────────── +"${PYTHON_BIN}" "${ROOT}/tools/prepare_mdbook_zh.py" \ + --source "${ROOT}/zh_chapters" \ + --summary-output "${ROOT}/zh_chapters/SUMMARY.md" + +mdbook build "${ROOT}/books/zh" diff --git a/en_chapters/SUMMARY.md b/en_chapters/SUMMARY.md new file mode 100644 index 0000000..9436c5d --- /dev/null +++ b/en_chapters/SUMMARY.md @@ -0,0 +1,3 @@ +# Summary + +[Machine Learning Systems: Design and Implementation](index.md) diff --git a/en_chapters/frontpage.html b/en_chapters/frontpage.html new file mode 100644 index 0000000..a18cd7f --- /dev/null +++ b/en_chapters/frontpage.html @@ -0,0 +1,507 @@ + + + + +
+
+ +
+
+
+
+

Machine Learning Systems: Design and Implementation

+

The first open-source book to comprehensively cover machine learning systems

+

Star

+ +
+
+ + +
+
+

Core Authors

+
+
+
+ +

Mai Luo

+

University of Edinburgh

+
+
+
+
+ +

Hao Dong

+

Peking University, Peng Cheng Laboratory

+
+
+
+
+ +

Xuefeng Jin

+

MindSpore Architect

+
+
+
+
+ +

Zhiliang Gan

+

MindSpore Architect

+
+
+ +
+

Chapter Authors

+
+
+
+ +

Cheng Lai

+

Peng Cheng Laboratory

+
+
+
+
+ +

Jiarong Han

+

Peng Cheng Laboratory

+
+
+
+
+ +

Yao Fu

+

University of Edinburgh

+
+
+
+
+ +

Xiulong Yuan

+

Tsinghua University

+
+
+ +
+
+ +

Zihan Ding

+

Princeton University

+
+
+
+
+ +

Jiankai Sun

+

Stanford University

+
+
+
+
+ +

Peiyuan Liao

+

Carnegie Mellon University

+
+
+
+
+ +

Wenteng Liang

+

Beijing University of Posts and Telecommunications

+
+
+
+
+ +

Jie Ren

+

University of Edinburgh

+
+
+
+
+ +

Hanchen Wang

+

University of Cambridge

+
+
+
+
+ +

Pei Mu

+

University of Edinburgh

+
+
+
+
+ +

Qinghua Zhang

+

Huawei Engineer

+
+
+
+
+ +

Zhibo Liang

+

Huawei Engineer

+
+
+
+
+ +

Jianfeng Yu

+

Huawei Engineer

+
+
+
+
+ +

Jinjin Chu

+

Huawei Engineer

+
+
+ +
+
+ +

Fubi Cai

+

Huawei Engineer

+
+
+
+
+ +

Renwei Zhang

+

Huawei Engineer

+
+
+
+
+ +

Chao Liu

+

Huawei Engineer

+
+
+
+
+ +

Gang Chen

+

Huawei Engineer

+
+
+ +
+
+ +

Mingqi Li

+

Huawei Engineer

+
+
+
+
+ +

Gangqiang Han

+

Huawei Engineer

+
+
+
+
+ +

Yehui Tang

+

Huawei Engineer

+
+
+
+
+ +

Zhiqiang Zhai

+

Huawei Engineer

+
+
+
+
+ +

Tiancheng Wu

+

Huawei Engineer

+
+
+
+
+ +

Xiaohui Li

+

Huawei Engineer

+
+
+
+
+ +

Haoyang Li

+

Huawei Engineer

+
+
+ +
+
+ +

Zhipeng Tan

+

Huawei Engineer

+
+
+
+
+ +

Shanni Li

+

Huawei Engineer

+
+
+
+
+ +

Zhijian Guo

+

Huawei Engineer

+
+
+ + +
+

Thanks to our contributors

+

and everyone who reported valuable errata and suggestions

+

Contribute to this Book

+
+
+ + +

Table of Contents

+ + + + diff --git a/en_chapters/img b/en_chapters/img deleted file mode 120000 index 0af1dd5..0000000 --- a/en_chapters/img +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/img \ No newline at end of file diff --git a/en_chapters/references b/en_chapters/references deleted file mode 120000 index 543a78f..0000000 --- a/en_chapters/references +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/references \ No newline at end of file diff --git a/en_chapters/static b/en_chapters/static deleted file mode 120000 index 1ca9b6a..0000000 --- a/en_chapters/static +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/static \ No newline at end of file diff --git a/static/frontpage.html b/static/frontpage.html index 2db5ba9..53094ea 100644 --- a/static/frontpage.html +++ b/static/frontpage.html @@ -201,6 +201,7 @@ a {

《机器学习系统:设计和实现》

做世界上第一本全面讲述机器学习系统知识的开源书籍

Star

+ @@ -477,4 +478,3 @@ for (i = 0; i < coll.length; i++) { - diff --git a/tests/test_assemble_docs_publish_tree.py b/tests/test_assemble_docs_publish_tree.py new file mode 100644 index 0000000..04e9bf6 --- /dev/null +++ b/tests/test_assemble_docs_publish_tree.py @@ -0,0 +1,87 @@ +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from tools.assemble_docs_publish_tree import assemble_publish_tree + + +class AssembleDocsPublishTreeTests(unittest.TestCase): + def test_assemble_publish_tree_uses_legacy_docs_layout(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + pages_repo = root / "pages" + en_source = root / "en-html" + zh_source = root / "zh-html" + + pages_repo.mkdir() + en_source.mkdir() + zh_source.mkdir() + + (en_source / "index.html").write_text("english home", encoding="utf-8") + (en_source / "guide.html").write_text("english guide", encoding="utf-8") + (zh_source / "index.html").write_text("chinese home", encoding="utf-8") + (zh_source / "searchindex.js").write_text("zh search", encoding="utf-8") + + assemble_publish_tree( + destination_root=pages_repo, + docs_subdir="docs", + en_source=en_source, + zh_source=zh_source, + ) + + self.assertEqual( + (pages_repo / "docs" / "index.html").read_text(encoding="utf-8"), + "english home", + ) + self.assertEqual( + (pages_repo / "docs" / "guide.html").read_text(encoding="utf-8"), + "english guide", + ) + self.assertEqual( + (pages_repo / "docs" / "cn" / "index.html").read_text(encoding="utf-8"), + "chinese home", + ) + self.assertEqual( + (pages_repo / "docs" / "cn" / "searchindex.js").read_text(encoding="utf-8"), + "zh search", + ) + + def test_assemble_publish_tree_replaces_stale_docs_content(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + pages_repo = root / "pages" + en_source = root / "en-html" + zh_source = root / "zh-html" + + (pages_repo / "docs" / "cn").mkdir(parents=True) + (pages_repo / "docs" / "old.html").write_text("stale en", encoding="utf-8") + (pages_repo / "docs" / "cn" / "old.html").write_text("stale zh", encoding="utf-8") + + en_source.mkdir() + zh_source.mkdir() + (en_source / "index.html").write_text("fresh en", encoding="utf-8") + (zh_source / "index.html").write_text("fresh zh", encoding="utf-8") + + assemble_publish_tree( + destination_root=pages_repo, + docs_subdir="docs", + en_source=en_source, + zh_source=zh_source, + ) + + self.assertFalse((pages_repo / "docs" / "old.html").exists()) + self.assertFalse((pages_repo / "docs" / "cn" / "old.html").exists()) + self.assertEqual( + (pages_repo / "docs" / "index.html").read_text(encoding="utf-8"), + "fresh en", + ) + self.assertEqual( + (pages_repo / "docs" / "cn" / "index.html").read_text(encoding="utf-8"), + "fresh zh", + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_dark_mode_images_css.py b/tests/test_dark_mode_images_css.py new file mode 100644 index 0000000..7d6ba70 --- /dev/null +++ b/tests/test_dark_mode_images_css.py @@ -0,0 +1,30 @@ +from __future__ import annotations + +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +class DarkModeImagesCssTests(unittest.TestCase): + def test_both_theme_css_files_style_dark_mode_body_images_only(self) -> None: + css_paths = [ + REPO_ROOT / "theme" / "dark-mode-images.css", + REPO_ROOT / "books" / "zh" / "theme" / "dark-mode-images.css", + ] + + for css_path in css_paths: + css = css_path.read_text(encoding="utf-8") + + self.assertIn(".navy .content main img", css, css_path.as_posix()) + self.assertIn(".coal .content main img", css, css_path.as_posix()) + self.assertIn(".ayu .content main img", css, css_path.as_posix()) + self.assertIn("background-color: #e8e8e8;", css, css_path.as_posix()) + self.assertIn(".openmlsys-frontpage img", css, css_path.as_posix()) + self.assertIn("background-color: transparent !important;", css, css_path.as_posix()) + self.assertIn("padding: 0 !important;", css, css_path.as_posix()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_ensure_book_resources.py b/tests/test_ensure_book_resources.py new file mode 100644 index 0000000..98304e3 --- /dev/null +++ b/tests/test_ensure_book_resources.py @@ -0,0 +1,55 @@ +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from tools.ensure_book_resources import ensure_resource_views + + +class EnsureBookResourcesTests(unittest.TestCase): + def test_ensure_resource_views_creates_missing_symlinks(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + chapter_dir = root / "en_chapters" + chapter_dir.mkdir() + + for directory in ("img", "references", "static"): + (root / directory).mkdir() + (root / "mlsys.bib").write_text("bib", encoding="utf-8") + + ensure_resource_views(chapter_dir, root) + + for name in ("img", "references", "static", "mlsys.bib"): + path = chapter_dir / name + self.assertTrue(path.is_symlink(), f"{name} should be a symlink") + self.assertEqual(path.resolve(), (root / name).resolve()) + + def test_ensure_resource_views_keeps_existing_non_symlink_paths(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + chapter_dir = root / "en_chapters" + chapter_dir.mkdir() + + for directory in ("img", "references", "static"): + (root / directory).mkdir() + (root / "mlsys.bib").write_text("root bib", encoding="utf-8") + + local_bib = chapter_dir / "mlsys.bib" + local_bib.write_text("local bib", encoding="utf-8") + local_static = chapter_dir / "static" + local_static.mkdir() + (local_static / "frontpage.html").write_text("local static", encoding="utf-8") + + ensure_resource_views(chapter_dir, root) + + self.assertFalse(local_bib.is_symlink()) + self.assertEqual(local_bib.read_text(encoding="utf-8"), "local bib") + self.assertFalse(local_static.is_symlink()) + self.assertTrue((local_static / "frontpage.html").exists()) + self.assertTrue((chapter_dir / "img").is_symlink()) + self.assertTrue((chapter_dir / "references").is_symlink()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_ensure_mdbook_typst_math.py b/tests/test_ensure_mdbook_typst_math.py new file mode 100644 index 0000000..7887c0a --- /dev/null +++ b/tests/test_ensure_mdbook_typst_math.py @@ -0,0 +1,134 @@ +from __future__ import annotations + +import gzip +import hashlib +import os +import tempfile +import unittest +from pathlib import Path +from unittest.mock import patch + +from tools.ensure_mdbook_typst_math import ( + ASSET_SHA256, + VERSION, + build_download_url, + ensure_binary, + resolve_asset_name, + resolve_binary_path, + resolve_version_path, +) + + +class ResolveAssetNameTests(unittest.TestCase): + def test_resolve_asset_name_for_supported_targets(self) -> None: + self.assertEqual( + resolve_asset_name(system="Darwin", machine="arm64"), + "mdbook-typst-math-aarch64-apple-darwin.gz", + ) + self.assertEqual( + resolve_asset_name(system="Darwin", machine="x86_64"), + "mdbook-typst-math-x86_64-apple-darwin.gz", + ) + self.assertEqual( + resolve_asset_name(system="Linux", machine="aarch64"), + "mdbook-typst-math-aarch64-unknown-linux-gnu.gz", + ) + self.assertEqual( + resolve_asset_name(system="Linux", machine="AMD64"), + "mdbook-typst-math-x86_64-unknown-linux-gnu.gz", + ) + self.assertEqual( + resolve_asset_name(system="Windows", machine="AMD64"), + "mdbook-typst-math-x86_64-pc-windows-msvc.exe", + ) + + def test_resolve_asset_name_rejects_unsupported_targets(self) -> None: + with self.assertRaises(ValueError): + resolve_asset_name(system="Linux", machine="riscv64") + + +class EnsureBinaryTests(unittest.TestCase): + def test_ensure_binary_downloads_and_extracts_gzip_release(self) -> None: + payload = b"linux-binary" + asset_name = "mdbook-typst-math-x86_64-unknown-linux-gnu.gz" + + with tempfile.TemporaryDirectory() as tmpdir: + output_dir = Path(tmpdir) + urls: list[str] = [] + + def fake_downloader(url: str) -> bytes: + urls.append(url) + return gzip.compress(payload) + + with patch.dict(ASSET_SHA256, {asset_name: hashlib.sha256(gzip.compress(payload)).hexdigest()}): + binary_path = ensure_binary( + output_dir, + system="Linux", + machine="x86_64", + downloader=fake_downloader, + ) + + self.assertEqual(binary_path, resolve_binary_path(output_dir, VERSION, asset_name)) + self.assertEqual(binary_path.name, "mdbook-typst-math") + self.assertEqual(binary_path.read_bytes(), payload) + self.assertEqual(resolve_version_path(output_dir).read_text(encoding="utf-8"), VERSION) + self.assertEqual(urls, [build_download_url(VERSION, asset_name)]) + self.assertTrue(os.access(binary_path, os.X_OK)) + + def test_ensure_binary_uses_cached_file_without_downloading(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + output_dir = Path(tmpdir) + asset_name = "mdbook-typst-math-x86_64-unknown-linux-gnu.gz" + cached_binary = resolve_binary_path(output_dir, VERSION, asset_name) + output_dir.mkdir(parents=True, exist_ok=True) + cached_binary.write_bytes(b"cached") + cached_binary.chmod(0o755) + resolve_version_path(output_dir).write_text(VERSION, encoding="utf-8") + + def fail_downloader(_: str) -> bytes: + raise AssertionError("downloader should not be called for cached binary") + + binary_path = ensure_binary( + output_dir, + system="Linux", + machine="x86_64", + downloader=fail_downloader, + ) + + self.assertEqual(binary_path, cached_binary) + self.assertEqual(binary_path.read_bytes(), b"cached") + + def test_ensure_binary_keeps_windows_extension(self) -> None: + payload = b"windows-binary" + asset_name = "mdbook-typst-math-x86_64-pc-windows-msvc.exe" + + with tempfile.TemporaryDirectory() as tmpdir: + output_dir = Path(tmpdir) + + def fake_downloader(_: str) -> bytes: + return payload + + with patch.dict(ASSET_SHA256, {asset_name: hashlib.sha256(payload).hexdigest()}): + binary_path = ensure_binary( + output_dir, + system="Windows", + machine="AMD64", + downloader=fake_downloader, + ) + + self.assertEqual(binary_path.name, "mdbook-typst-math.exe") + self.assertEqual(binary_path.read_bytes(), payload) + + def test_ensure_binary_rejects_checksum_mismatch(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + with self.assertRaises(ValueError): + ensure_binary( + Path(tmpdir), + system="Linux", + machine="x86_64", + downloader=lambda _: gzip.compress(b"bad-binary"), + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_mdbook_typst_math.py b/tests/test_mdbook_typst_math.py new file mode 100644 index 0000000..3d99d33 --- /dev/null +++ b/tests/test_mdbook_typst_math.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import unittest +from pathlib import Path + + +REPO_ROOT = Path(__file__).resolve().parents[1] +BOOK_PATHS = ( + REPO_ROOT / "book.toml", + REPO_ROOT / "books" / "zh" / "book.toml", +) +BUILD_SCRIPTS = ( + REPO_ROOT / "build_mdbook.sh", + REPO_ROOT / "build_mdbook_zh.sh", +) + + +class MdBookTypstMathConfigTests(unittest.TestCase): + def test_books_use_typst_math_without_mathjax(self) -> None: + for path in BOOK_PATHS: + config = path.read_text(encoding="utf-8") + + self.assertIn("[preprocessor.typst-math]", config, path.as_posix()) + self.assertIn("theme/typst.css", config, path.as_posix()) + self.assertNotIn("mathjax-support = true", config, path.as_posix()) + + def test_build_scripts_bootstrap_prebuilt_typst_math_binary(self) -> None: + for path in BUILD_SCRIPTS: + script = path.read_text(encoding="utf-8") + + self.assertIn("ensure_mdbook_typst_math.py", script, path.as_posix()) + self.assertIn("MDBOOK_TYPST_MATH_BIN_DIR", script, path.as_posix()) + self.assertIn("export PATH=", script, path.as_posix()) + self.assertNotIn("cargo install mdbook-typst-math", script, path.as_posix()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_prepare_mdbook.py b/tests/test_prepare_mdbook.py new file mode 100644 index 0000000..231510b --- /dev/null +++ b/tests/test_prepare_mdbook.py @@ -0,0 +1,237 @@ +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from tools.prepare_mdbook import build_title_cache, rewrite_markdown, write_summary + + +REPO_ROOT = Path(__file__).resolve().parents[1] + + +class PrepareMdBookTests(unittest.TestCase): + def test_write_summary_skips_placeholder_pages(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "en_chapters" + source.mkdir() + + (source / "index.md").write_text( + """Machine Learning Systems +======================== + +```toc +:maxdepth: 2 + +chapter_preface/index +chapter_introduction/index +``` + +```toc +:maxdepth: 1 + +appendix/index +``` +""", + encoding="utf-8", + ) + + chapter_preface = source / "chapter_preface" + chapter_preface.mkdir() + (chapter_preface / "index.md").write_text( + "[TODO: src = zh_chapters/chapter_preface/index.md]\n", + encoding="utf-8", + ) + + chapter_intro = source / "chapter_introduction" + chapter_intro.mkdir() + (chapter_intro / "index.md").write_text("# Introduction\n", encoding="utf-8") + + appendix = source / "appendix" + appendix.mkdir() + (appendix / "index.md").write_text("# Appendix\n", encoding="utf-8") + + summary_path = write_summary( + source, + placeholder_prefix="[TODO: src = zh_chapters/", + ) + summary = summary_path.read_text(encoding="utf-8") + + self.assertEqual( + summary, + """# Summary + +[Machine Learning Systems](index.md) +[Introduction](chapter_introduction/index.md) +[Appendix](appendix/index.md) +""", + ) + + title_cache = build_title_cache( + source, + placeholder_prefix="[TODO: src = zh_chapters/", + ) + rewritten = rewrite_markdown( + (source / "index.md").read_text(encoding="utf-8"), + (source / "index.md").resolve(), + title_cache, + ) + + self.assertIn("- [Introduction](chapter_introduction/index.md)", rewritten) + self.assertIn("- [Appendix](appendix/index.md)", rewritten) + self.assertNotIn("chapter_preface/index.md", rewritten) + + def test_rewrite_markdown_uses_configured_bibliography_title(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + page = root / "chapter.md" + page.write_text( + """# Introduction + +Reference :cite:`smith2024`. +""", + encoding="utf-8", + ) + + rewritten = rewrite_markdown( + page.read_text(encoding="utf-8"), + page.resolve(), + {page.resolve(): "Introduction"}, + bib_db={ + "smith2024": { + "author": "Smith, Alice and Doe, Bob", + "title": "Systems Paper", + "year": "2024", + "journal": "ML Systems Journal", + } + }, + bibliography_title="References", + ) + + self.assertIn("## References", rewritten) + self.assertNotIn("## 参考文献", rewritten) + + def test_rewrite_markdown_inlines_frontpage_with_language_switch(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "en_chapters" + static_dir = source / "static" + static_dir.mkdir(parents=True) + + index = source / "index.md" + index.write_text( + """# Home + +```eval_rst +.. raw:: html + :file: frontpage.html +``` +""", + encoding="utf-8", + ) + (static_dir / "frontpage.html").write_text( + "

STAR

\n\n
frontpage
\n", + encoding="utf-8", + ) + + rewritten = rewrite_markdown( + index.read_text(encoding="utf-8"), + index.resolve(), + {index.resolve(): "Home"}, + frontpage_switch_label="中文", + frontpage_switch_href="cn/", + ) + + self.assertIn('class="openmlsys-frontpage-switch-row"', rewritten) + self.assertIn('class="openmlsys-frontpage-switch"', rewritten) + self.assertIn('href="cn/"', rewritten) + self.assertIn(">中文", rewritten) + self.assertLess( + rewritten.index('class="star-slot"'), + rewritten.index('class="openmlsys-frontpage-switch-row"'), + ) + + def test_rewrite_markdown_prefers_book_local_frontpage_file(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "en_chapters" + static_dir = source / "static" + source.mkdir() + static_dir.mkdir() + + index = source / "index.md" + index.write_text( + """# Home + +```eval_rst +.. raw:: html + :file: frontpage.html +``` +""", + encoding="utf-8", + ) + (source / "frontpage.html").write_text( + "
English frontpage
\n", + encoding="utf-8", + ) + (static_dir / "frontpage.html").write_text( + "
Chinese fallback
\n", + encoding="utf-8", + ) + + rewritten = rewrite_markdown( + index.read_text(encoding="utf-8"), + index.resolve(), + {index.resolve(): "Home"}, + ) + + self.assertIn("English frontpage", rewritten) + self.assertNotIn("Chinese fallback", rewritten) + self.assertIn("background: transparent !important;", rewritten) + self.assertIn("padding: 0 !important;", rewritten) + self.assertIn("border-radius: 6px;", rewritten) + self.assertIn("background: #f6f8fa;", rewritten) + self.assertIn(".content main {", rewritten) + self.assertIn("max-width: min(100%, max(65%, var(--content-max-width)));", rewritten) + self.assertIn(".openmlsys-frontpage {", rewritten) + self.assertIn("width: 100%;", rewritten) + self.assertIn("margin-inline: auto;", rewritten) + + def test_regular_page_does_not_render_frontpage_switch(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + page = root / "chapter.md" + page.write_text("# Chapter\n\nRegular body.\n", encoding="utf-8") + + rewritten = rewrite_markdown( + page.read_text(encoding="utf-8"), + page.resolve(), + {page.resolve(): "Chapter"}, + frontpage_switch_label="中文", + frontpage_switch_href="cn/", + ) + + self.assertNotIn('openmlsys-frontpage-switch', rewritten) + + def test_english_frontpage_author_grid_uses_top_aligned_spacing(self) -> None: + frontpage = (REPO_ROOT / "en_chapters" / "frontpage.html").read_text(encoding="utf-8") + + self.assertIn(".authors.mdl-grid {", frontpage) + self.assertIn("align-items: flex-start;", frontpage) + self.assertIn("row-gap: calc(24px + 1.5em);", frontpage) + self.assertIn("height: 120px;", frontpage) + self.assertIn("object-fit: cover;", frontpage) + + def test_english_frontpage_footer_titles_are_stacked_not_flex_columns(self) -> None: + frontpage = (REPO_ROOT / "en_chapters" / "frontpage.html").read_text(encoding="utf-8") + + self.assertIn(".authors .mdl-cell:not(.author-group-title) {", frontpage) + self.assertIn(".author-group-title {", frontpage) + self.assertIn("display: block;", frontpage) + self.assertIn(".author-group-title h3,", frontpage) + self.assertIn("width: 100%;", frontpage) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_prepare_mdbook_zh.py b/tests/test_prepare_mdbook_zh.py new file mode 100644 index 0000000..13ac43c --- /dev/null +++ b/tests/test_prepare_mdbook_zh.py @@ -0,0 +1,266 @@ +from __future__ import annotations + +import tempfile +import unittest +from pathlib import Path + +from tools.prepare_mdbook_zh import extract_title, process_equation_labels, rewrite_markdown, write_summary + + +class PrepareMdBookZhTests(unittest.TestCase): + def test_extract_title_supports_atx_and_setext_headings(self) -> None: + self.assertEqual(extract_title("# 导论\n"), "导论") + self.assertEqual(extract_title("前言文字\n\n## 机器学习应用\n"), "机器学习应用") + self.assertEqual(extract_title("机器学习系统:设计和实现\n=========================\n"), "机器学习系统:设计和实现") + + def test_write_summary_generates_nested_navigation(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "zh_chapters" + source.mkdir() + + (source / "index.md").write_text( + """机器学习系统:设计和实现 +========================= + +```eval_rst +.. raw:: html + :file: frontpage.html +``` + +```toc +:maxdepth: 2 + +[前言](chapter_preface/index) + +# 基础篇 +chapter_introduction/index + +# 附录 +[机器学习基础附录](appendix_machine_learning_introduction/index) +``` +""", + encoding="utf-8", + ) + + chapter_preface = source / "chapter_preface" + chapter_preface.mkdir() + (chapter_preface / "index.md").write_text("# 前言\n", encoding="utf-8") + static_dir = source / "static" + static_dir.mkdir() + (static_dir / "frontpage.html").write_text( + "
frontpage
\n", + encoding="utf-8", + ) + + chapter_intro = source / "chapter_introduction" + chapter_intro.mkdir() + (chapter_intro / "index.md").write_text( + """# 导论 + +```toc +:maxdepth: 2 + +applications +design +``` +""", + encoding="utf-8", + ) + (chapter_intro / "applications.md").write_text("# 机器学习应用\n", encoding="utf-8") + (chapter_intro / "design.md").write_text("# 设计目标\n", encoding="utf-8") + + appendix = source / "appendix_machine_learning_introduction" + appendix.mkdir() + (appendix / "index.md").write_text("# 机器学习基础附录\n", encoding="utf-8") + + for name in ("img", "static", "references"): + (root / name).mkdir() + (root / "mlsys.bib").write_text("% bibliography\n", encoding="utf-8") + + summary_path = write_summary(source) + summary = summary_path.read_text(encoding="utf-8") + self.assertEqual( + summary, + """# Summary + +[机器学习系统:设计和实现](index.md) +[前言](chapter_preface/index.md) + +# 基础篇 + +- [导论](chapter_introduction/index.md) + - [机器学习应用](chapter_introduction/applications.md) + - [设计目标](chapter_introduction/design.md) + +# 附录 + +- [机器学习基础附录](appendix_machine_learning_introduction/index.md) +""", + ) + + title_cache = { + (source / "chapter_preface" / "index.md").resolve(): "前言", + (source / "chapter_introduction" / "index.md").resolve(): "导论", + (source / "chapter_introduction" / "applications.md").resolve(): "机器学习应用", + (source / "chapter_introduction" / "design.md").resolve(): "设计目标", + (source / "appendix_machine_learning_introduction" / "index.md").resolve(): "机器学习基础附录", + } + root_index = rewrite_markdown((source / "index.md").read_text(encoding="utf-8"), (source / "index.md").resolve(), title_cache) + self.assertNotIn("```eval_rst", root_index) + self.assertNotIn("```toc", root_index) + self.assertIn("- [前言](chapter_preface/index.md)", root_index) + self.assertIn("- 基础篇", root_index) + self.assertIn(" - [导论](chapter_introduction/index.md)", root_index) + self.assertIn("- 附录", root_index) + self.assertIn(" - [机器学习基础附录](appendix_machine_learning_introduction/index.md)", root_index) + + intro_index = rewrite_markdown( + (source / "chapter_introduction" / "index.md").read_text(encoding="utf-8"), + (source / "chapter_introduction" / "index.md").resolve(), + title_cache, + ) + self.assertNotIn("```toc", intro_index) + self.assertIn("- [机器学习应用](applications.md)", intro_index) + self.assertIn("- [设计目标](design.md)", intro_index) + + def test_write_summary_raises_for_missing_toc_entries(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "zh_chapters" + source.mkdir() + + (source / "index.md").write_text( + """# 首页 + +```toc +:maxdepth: 2 + +existing +missing +``` +""", + encoding="utf-8", + ) + (source / "existing.md").write_text("# 现有章节\n", encoding="utf-8") + + with self.assertRaises(FileNotFoundError): + write_summary(source) + + def test_rewrite_markdown_normalizes_common_d2l_directives(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "zh_chapters" + source.mkdir() + + page = source / "chapter.md" + page.write_text( + """# 标题 + +![配图](../img/example.png) +:width:`800px` +:label:`fig_example` + +参见 :numref:`fig_example` 和公式 :eqref:`eq_example`,引用 :cite:`foo2024`。 +""", + encoding="utf-8", + ) + + rewritten = rewrite_markdown(page.read_text(encoding="utf-8"), page.resolve(), {page.resolve(): "标题"}) + self.assertNotIn(":width:", rewritten) + self.assertNotIn(":label:", rewritten) + self.assertNotIn(":numref:", rewritten) + self.assertNotIn(":eqref:", rewritten) + self.assertNotIn(":cite:", rewritten) + self.assertIn("`fig_example`", rewritten) + self.assertIn("$\\eqref{eq_example}$", rewritten) + self.assertIn("[foo2024]", rewritten) + + def test_rewrite_markdown_inlines_frontpage_html_include(self) -> None: + with tempfile.TemporaryDirectory() as tmpdir: + root = Path(tmpdir) + source = root / "zh_chapters" + static_dir = source / "static" + static_dir.mkdir(parents=True) + + index = source / "index.md" + index.write_text( + """# 首页 + +```eval_rst +.. raw:: html + :file: frontpage.html +``` +""", + encoding="utf-8", + ) + (static_dir / "frontpage.html").write_text( + """ + + +

STAR

+ +
+ + +
+ +""", + encoding="utf-8", + ) + + rewritten = rewrite_markdown(index.read_text(encoding="utf-8"), index.resolve(), {index.resolve(): "首页"}) + self.assertNotIn("```eval_rst", rewritten) + self.assertNotIn("", rewritten) + self.assertIn('class="openmlsys-frontpage"', rewritten) + self.assertIn('
', rewritten) + self.assertIn('", re.IGNORECASE | re.DOTALL) +DEFAULT_BIBLIOGRAPHY_TITLE = "References" +FRONTPAGE_SWITCH_PLACEHOLDER = "" +FRONTPAGE_LAYOUT_CSS = """ + +""".strip() + + +@dataclass(frozen=True) +class TocItem: + kind: str + label: str + target: str | None = None + + +def is_placeholder_markdown(markdown: str, placeholder_prefix: str | None = None) -> bool: + if not placeholder_prefix: + return False + + stripped = markdown.strip() + return stripped.startswith(placeholder_prefix) and stripped.endswith("]") + + +def extract_title(markdown: str, fallback: str = "Untitled") -> str: + lines = markdown.splitlines() + + for index, line in enumerate(lines): + stripped = line.strip() + if not stripped: + continue + if stripped.startswith("#"): + heading = stripped.lstrip("#").strip() + if heading: + return heading + + next_index = index + 1 + if next_index < len(lines): + underline = lines[next_index].strip() + if underline and set(underline) <= {"=", "-"}: + return stripped + + return fallback + + +def parse_toc_entries(block_lines: list[str]) -> list[TocItem]: + entries: list[TocItem] = [] + for line in block_lines: + stripped = line.strip() + if not stripped or stripped.startswith(":"): + continue + part_match = TOC_PART_RE.match(stripped) + if part_match: + entries.append(TocItem(kind="part", label=part_match.group(1).strip())) + continue + link_match = TOC_LINK_RE.match(stripped) + if link_match: + entries.append( + TocItem( + kind="chapter", + label=link_match.group(1).strip(), + target=link_match.group(2).strip(), + ) + ) + continue + entries.append(TocItem(kind="chapter", label="", target=stripped)) + return entries + + +def parse_toc_blocks(markdown: str) -> list[list[TocItem]]: + blocks: list[list[TocItem]] = [] + lines = markdown.splitlines() + index = 0 + + while index < len(lines): + if lines[index].strip() == f"```{TOC_FENCE}": + index += 1 + block_lines: list[str] = [] + while index < len(lines) and lines[index].strip() != "```": + block_lines.append(lines[index]) + index += 1 + entries = parse_toc_entries(block_lines) + blocks.append(entries) + index += 1 + + return blocks + + +def resolve_toc_target(current_file: Path, entry: str) -> Path: + target_name = entry if entry.endswith(".md") else f"{entry}.md" + target = (current_file.parent / target_name).resolve() + if not target.exists(): + raise FileNotFoundError(f"TOC entry '{entry}' from '{current_file}' does not exist") + return target + + +def relative_link(from_file: Path, target_file: Path) -> str: + return Path(os.path.relpath(target_file, start=from_file.parent)).as_posix() + + +def _strip_latex_escapes_outside_math(text: str) -> str: + """Remove LaTeX text-mode escapes (``\\_``, ``\\#``, etc.) outside math + spans, fenced code blocks, and inline code. + + Operates on the full text (not per-line) to correctly handle multi-line + display math ``$$...$$`` blocks. + """ + # 1. Find all protected regions where escapes must NOT be stripped. + protected: list[tuple[int, int]] = [] # (start, end) + n = len(text) + i = 0 + in_fence: str | None = None + fence_start = 0 + + while i < n: + # Fenced code blocks (``` or ~~~) at start of line + if (i == 0 or text[i - 1] == "\n") and text[i] in ("`", "~"): + m = re.match(r"`{3,}|~{3,}", text[i:]) + if m: + if in_fence is None: + in_fence = m.group()[0] + fence_start = i + elif m.group()[0] == in_fence: + eol = text.find("\n", m.end() + i) + end = eol + 1 if eol != -1 else n + protected.append((fence_start, end)) + in_fence = None + i = end + continue + eol = text.find("\n", i) + i = eol + 1 if eol != -1 else n + continue + + if in_fence is not None: + i += 1 + continue + + # Inline code `...` + if text[i] == "`": + close = text.find("`", i + 1) + if close != -1: + protected.append((i, close + 1)) + i = close + 1 + continue + + # Display math $$...$$ + if text[i:i + 2] == "$$": + close = text.find("$$", i + 2) + if close != -1: + protected.append((i, close + 2)) + i = close + 2 + continue + + # Inline math $...$ + if text[i] == "$": + j = i + 1 + while j < n and text[j] != "$" and text[j] != "\n": + j += 1 + if j < n and text[j] == "$" and j > i + 1: + protected.append((i, j + 1)) + i = j + 1 + continue + + i += 1 + + # Unclosed fence → protect everything from fence_start to end + if in_fence is not None: + protected.append((fence_start, n)) + + # 2. Apply substitution only to unprotected gaps. + parts: list[str] = [] + prev = 0 + for start, end in protected: + if start > prev: + parts.append(LATEX_ESCAPE_RE.sub(r"\1", text[prev:start])) + parts.append(text[start:end]) + prev = end + if prev < n: + parts.append(LATEX_ESCAPE_RE.sub(r"\1", text[prev:])) + + return "".join(parts) + + +def process_equation_labels(markdown: str) -> tuple[str, dict[str, int]]: + """Convert :eqlabel: directives to MathJax \\tag + \\label in preceding equations. + + Args: + markdown: The markdown content to process. + + Returns: + A tuple of (processed_markdown, label_map) where label_map maps + label names to their equation numbers. + """ + lines = markdown.split("\n") + result: list[str] = [] + eq_counter = 0 + label_map: dict[str, int] = {} + + for line in lines: + match = EQLABEL_LINE_RE.match(line.strip()) + if not match: + result.append(line) + continue + + label_name = match.group(1) + eq_counter += 1 + label_map[label_name] = eq_counter + tag = f"\\tag{{{eq_counter}}}\\label{{{label_name}}}" + + # Search backward for the closing $$ of the preceding equation + inserted = False + for j in range(len(result) - 1, -1, -1): + stripped = result[j].rstrip() + if not stripped: + continue # skip blank lines + if stripped == "$$": + # Multi-line equation: $$ on its own line + result.insert(j, tag) + inserted = True + break + if stripped.endswith("$$"): + # Single-line or end-of-content $$ + result[j] = stripped[:-2] + tag + "$$" + inserted = True + break + break # non-blank, non-$$ line: no equation found + + if not inserted: + # Fallback: keep original line if no equation found + result.append(line) + + return "\n".join(result), label_map + + +def normalize_directives( + markdown: str, + label_map: dict[str, int] | None = None, +) -> str: + normalized = OPTION_LINE_RE.sub("", markdown) + normalized = NUMREF_RE.sub(lambda match: f"`{match.group(1)}`", normalized) + if label_map: + normalized = EQREF_RE.sub( + lambda m: f"({label_map[m.group(1)]})" if m.group(1) in label_map else f"$\\eqref{{{m.group(1)}}}$", + normalized, + ) + else: + normalized = EQREF_RE.sub(lambda match: f"$\\eqref{{{match.group(1)}}}$", normalized) + + normalized = _strip_latex_escapes_outside_math(normalized) + + lines = [line.rstrip() for line in normalized.splitlines()] + collapsed: list[str] = [] + previous_blank = False + for line in lines: + is_blank = line == "" + if is_blank and previous_blank: + continue + collapsed.append(line) + previous_blank = is_blank + + while collapsed and collapsed[-1] == "": + collapsed.pop() + + return "\n".join(collapsed) + "\n" + + +def clean_bibtex(value: str) -> str: + value = re.sub(r"\{\\[`'^\"~=.](\w)\}", r"\1", value) + value = re.sub(r"\\[`'^\"~=.](\w)", r"\1", value) + value = value.replace("{", "").replace("}", "") + return value.strip() + + +def _parse_bib_fields(body: str) -> dict[str, str]: + fields: dict[str, str] = {} + i = 0 + while i < len(body): + while i < len(body) and body[i] in " \t\n\r,": + i += 1 + if i >= len(body): + break + start = i + while i < len(body) and body[i] not in "= \t\n\r": + i += 1 + name = body[start:i].strip().lower() + while i < len(body) and body[i] != "=": + i += 1 + if i >= len(body): + break + i += 1 + while i < len(body) and body[i] in " \t\n\r": + i += 1 + if i >= len(body): + break + if body[i] == "{": + depth = 1 + i += 1 + vstart = i + while i < len(body) and depth > 0: + if body[i] == "{": + depth += 1 + elif body[i] == "}": + depth -= 1 + i += 1 + value = body[vstart : i - 1] + elif body[i] == '"': + i += 1 + vstart = i + while i < len(body) and body[i] != '"': + i += 1 + value = body[vstart:i] + i += 1 + else: + vstart = i + while i < len(body) and body[i] not in ", \t\n\r}": + i += 1 + value = body[vstart:i] + if name: + fields[name] = value.strip() + return fields + + +def parse_bib(bib_path: Path) -> dict[str, dict[str, str]]: + text = bib_path.read_text(encoding="utf-8") + entries: dict[str, dict[str, str]] = {} + for match in BIB_ENTRY_RE.finditer(text): + key = match.group(2).strip() + start = match.end() + depth = 1 + pos = start + while pos < len(text) and depth > 0: + if text[pos] == "{": + depth += 1 + elif text[pos] == "}": + depth -= 1 + pos += 1 + fields = _parse_bib_fields(text[start : pos - 1]) + fields["_type"] = match.group(1).lower() + entries[key] = fields + return entries + + +def _render_bibliography( + cited_keys: list[str], + bib_db: dict[str, dict[str, str]], + bibliography_title: str, +) -> list[str]: + lines: list[str] = ["---", "", f"## {bibliography_title}", "", "
    "] + for key in cited_keys: + entry = bib_db.get(key) + if not entry: + continue + author = clean_bibtex(entry.get("author", "")) + title = clean_bibtex(entry.get("title", "")) + year = entry.get("year", "") + venue = clean_bibtex(entry.get("journal", "") or entry.get("booktitle", "")) + parts: list[str] = [] + if author: + parts.append(author) + if title: + parts.append(f"{title}") + if venue: + parts.append(venue) + if year: + parts.append(year) + text = ". ".join(parts) + "." if parts else f"{key}." + lines.append(f'
  1. {text}
  2. ') + lines.append("
") + return lines + + +def process_citations( + markdown: str, + bib_db: dict[str, dict[str, str]], + bibliography_title: str = DEFAULT_BIBLIOGRAPHY_TITLE, +) -> str: + cited_keys: list[str] = [] + + def _replace_cite(match: re.Match[str]) -> str: + keys = [k.strip() for k in match.group(1).split(",")] + for key in keys: + if key not in cited_keys and key in bib_db: + cited_keys.append(key) + if not bib_db: + return "[" + ", ".join(keys) + "]" + nums: list[str] = [] + for key in keys: + if key not in bib_db: + continue + idx = cited_keys.index(key) + 1 + nums.append(f'[{idx}]') + return "".join(nums) + + processed = CITE_RE.sub(_replace_cite, markdown) + if cited_keys and bib_db: + bib_lines = _render_bibliography(cited_keys, bib_db, bibliography_title) + processed = processed.rstrip("\n") + "\n\n" + "\n".join(bib_lines) + "\n" + return processed + + +def resolve_raw_html_file(current_file: Path, filename: str) -> Path: + direct = (current_file.parent / filename).resolve() + if direct.exists(): + return direct + + static_fallback = (current_file.parent / "static" / filename).resolve() + if static_fallback.exists(): + return static_fallback + + repo_static = (Path(__file__).resolve().parent.parent / "static" / filename) + if repo_static.exists(): + return repo_static + + raise FileNotFoundError(f"Raw HTML include '{filename}' from '{current_file}' does not exist") + + +def rewrite_frontpage_assets(html: str) -> str: + rewritten = html.replace("./_images/", "static/image/") + rewritten = rewritten.replace("_images/", "static/image/") + rewritten = HEAD_TAG_RE.sub("", rewritten) + rewritten = STYLE_BLOCK_RE.sub(_minify_style_block, rewritten) + return rewritten + + +def _minify_style_block(match: re.Match[str]) -> str: + content = match.group(1) + parts = [line.strip() for line in content.splitlines() if line.strip()] + return f"" + + +def render_frontpage_switch(label: str, href: str) -> str: + return ( + '

' + f'{label}' + "

" + ) + + +def wrap_frontpage_html( + html: str, + frontpage_switch_label: str | None = None, + frontpage_switch_href: str | None = None, +) -> str: + rendered_html = html.strip() + if frontpage_switch_label and frontpage_switch_href: + switch_html = render_frontpage_switch(frontpage_switch_label, frontpage_switch_href) + if FRONTPAGE_SWITCH_PLACEHOLDER in rendered_html: + rendered_html = rendered_html.replace(FRONTPAGE_SWITCH_PLACEHOLDER, switch_html) + else: + rendered_html = "\n".join([switch_html, rendered_html]) + + parts = [FRONTPAGE_LAYOUT_CSS, '
', rendered_html, "
"] + return "\n".join(parts) + + +def inline_raw_html( + block_lines: list[str], + current_file: Path, + frontpage_switch_label: str | None = None, + frontpage_switch_href: str | None = None, +) -> str | None: + stripped = [line.strip() for line in block_lines if line.strip()] + if not stripped or stripped[0] != ".. raw:: html": + return None + + filename: str | None = None + for line in stripped[1:]: + match = RAW_HTML_FILE_RE.match(line) + if match: + filename = match.group(1) + break + + if filename is None: + return None + + html_path = resolve_raw_html_file(current_file, filename) + html = rewrite_frontpage_assets(html_path.read_text(encoding="utf-8")).strip() + if Path(filename).name == "frontpage.html": + return wrap_frontpage_html( + html, + frontpage_switch_label=frontpage_switch_label, + frontpage_switch_href=frontpage_switch_href, + ) + return html + + +def chapter_label(item: TocItem, target: Path, title_cache: dict[Path, str]) -> str: + return item.label or title_cache[target] + + +def render_toc_list(entries: list[TocItem], current_file: Path, title_cache: dict[Path, str]) -> list[str]: + rendered: list[str] = [] + current_indent = 0 + for entry in entries: + if entry.kind == "part": + rendered.append(f"- {entry.label}") + current_indent = 1 + continue + + if entry.target is None: + continue + + target = resolve_toc_target(current_file, entry.target) + if target not in title_cache: + continue + + label = chapter_label(entry, target, title_cache) + rendered.append(f"{' ' * current_indent}- [{label}]({relative_link(current_file, target)})") + return rendered + + +def rewrite_markdown( + markdown: str, + current_file: Path, + title_cache: dict[Path, str], + bib_db: dict[str, dict[str, str]] | None = None, + bibliography_title: str = DEFAULT_BIBLIOGRAPHY_TITLE, + frontpage_switch_label: str | None = None, + frontpage_switch_href: str | None = None, +) -> str: + output: list[str] = [] + lines = markdown.splitlines() + index = 0 + + while index < len(lines): + stripped = lines[index].strip() + if stripped in (f"```{TOC_FENCE}", f"```{EVAL_RST_FENCE}"): + fence = stripped[3:] + index += 1 + block_lines: list[str] = [] + while index < len(lines) and lines[index].strip() != "```": + block_lines.append(lines[index]) + index += 1 + + if fence == TOC_FENCE: + entries = parse_toc_entries(block_lines) + if entries: + if output and output[-1] != "": + output.append("") + rendered = render_toc_list(entries, current_file, title_cache) + output.extend(rendered) + if rendered and output and output[-1] != "": + output.append("") + elif fence == EVAL_RST_FENCE: + raw_html = inline_raw_html( + block_lines, + current_file, + frontpage_switch_label=frontpage_switch_label, + frontpage_switch_href=frontpage_switch_href, + ) + if raw_html: + if output and output[-1] != "": + output.append("") + output.extend(raw_html.splitlines()) + if output and output[-1] != "": + output.append("") + index += 1 + continue + + output.append(lines[index]) + index += 1 + + while output and output[-1] == "": + output.pop() + + raw = "\n".join(output) + "\n" + result, label_map = process_equation_labels(raw) + result = normalize_directives(result, label_map=label_map) + result = process_citations(result, bib_db or {}, bibliography_title=bibliography_title) + return result + + +def build_title_cache( + source_dir: Path, + placeholder_prefix: str | None = None, +) -> dict[Path, str]: + cache: dict[Path, str] = {} + for markdown_file in sorted(source_dir.rglob("*.md")): + if "_build" in markdown_file.parts or markdown_file.name == "SUMMARY.md": + continue + text = markdown_file.read_text(encoding="utf-8") + if is_placeholder_markdown(text, placeholder_prefix): + continue + cache[markdown_file.resolve()] = extract_title(text, fallback=markdown_file.stem) + return cache + + +def build_summary(source_dir: Path, title_cache: dict[Path, str]) -> str: + root_index = (source_dir / "index.md").resolve() + root_markdown = root_index.read_text(encoding="utf-8") + + lines = ["# Summary", "", f"[{title_cache[root_index]}](index.md)"] + seen: set[Path] = {root_index} + + def append_entry(target: Path, indent: int, label: str | None = None) -> None: + target = target.resolve() + if target in seen or target not in title_cache: + return + seen.add(target) + rel = target.relative_to(source_dir.resolve()).as_posix() + title = label or title_cache[target] + lines.append(f"{' ' * indent}- [{title}]({rel})") + + child_markdown = target.read_text(encoding="utf-8") + for block in parse_toc_blocks(child_markdown): + for entry in block: + if entry.kind != "chapter" or entry.target is None: + continue + append_entry(resolve_toc_target(target, entry.target), indent + 1, entry.label or None) + + def append_prefix_chapter(target: Path, label: str | None = None) -> None: + target = target.resolve() + if target in seen or target not in title_cache: + return + seen.add(target) + rel = target.relative_to(source_dir.resolve()).as_posix() + title = label or title_cache[target] + lines.append(f"[{title}]({rel})") + + numbered_started = False + for block in parse_toc_blocks(root_markdown): + for entry in block: + if entry.kind == "part": + if lines and lines[-1] != "": + lines.append("") + lines.append(f"# {entry.label}") + lines.append("") + numbered_started = True + continue + + if entry.target is None: + continue + + target = resolve_toc_target(root_index, entry.target) + if numbered_started: + append_entry(target, 0, entry.label or None) + else: + append_prefix_chapter(target, entry.label or None) + + return "\n".join(lines) + "\n" + + +def write_summary( + source_dir: Path, + summary_path: Path | None = None, + placeholder_prefix: str | None = None, +) -> Path: + source_dir = source_dir.resolve() + summary_path = summary_path.resolve() if summary_path else (source_dir / "SUMMARY.md") + title_cache = build_title_cache(source_dir, placeholder_prefix=placeholder_prefix) + summary_path.write_text(build_summary(source_dir, title_cache), encoding="utf-8") + return summary_path + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Generate mdBook SUMMARY.md for a chapter directory.") + parser.add_argument("--source", type=Path, required=True, help="Source chapter directory") + parser.add_argument("--summary-output", type=Path, required=True, help="Where to write the generated SUMMARY.md") + parser.add_argument( + "--placeholder-prefix", + default=None, + help="If set, files whose entire contents start with this prefix are skipped from mdBook output.", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + summary_path = write_summary( + args.source, + summary_path=args.summary_output, + placeholder_prefix=args.placeholder_prefix, + ) + print(f"Wrote mdBook summary to {summary_path}") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tools/prepare_mdbook_zh.py b/tools/prepare_mdbook_zh.py new file mode 100644 index 0000000..91de6e4 --- /dev/null +++ b/tools/prepare_mdbook_zh.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import argparse +from pathlib import Path + +try: + from tools.prepare_mdbook import ( + build_title_cache, + extract_title, + inline_raw_html, + parse_bib, + process_equation_labels, + rewrite_markdown, + write_summary, + ) +except ModuleNotFoundError: + from prepare_mdbook import ( + build_title_cache, + extract_title, + inline_raw_html, + parse_bib, + process_equation_labels, + rewrite_markdown, + write_summary, + ) + + +FRONTPAGE_SWITCH_LABEL = "English" +FRONTPAGE_SWITCH_HREF = "../" + + +def parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Generate mdBook SUMMARY.md for zh_chapters.") + parser.add_argument("--source", type=Path, default=Path("zh_chapters"), help="Source chapter directory") + parser.add_argument( + "--summary-output", + type=Path, + default=Path("zh_chapters/SUMMARY.md"), + help="Where to write the generated SUMMARY.md", + ) + return parser.parse_args() + + +def main() -> int: + args = parse_args() + summary_path = write_summary(args.source, summary_path=args.summary_output) + print(f"Wrote mdBook summary to {summary_path}") + return 0 + + +def rewrite_markdown( + markdown: str, + current_file: Path, + title_cache: dict[Path, str], + bib_db: dict[str, dict[str, str]] | None = None, + bibliography_title: str = "参考文献", +) -> str: + try: + from tools.prepare_mdbook import rewrite_markdown as generic_rewrite_markdown + except ModuleNotFoundError: + from prepare_mdbook import rewrite_markdown as generic_rewrite_markdown + + return generic_rewrite_markdown( + markdown, + current_file, + title_cache, + bib_db=bib_db, + bibliography_title=bibliography_title, + frontpage_switch_label=FRONTPAGE_SWITCH_LABEL, + frontpage_switch_href=FRONTPAGE_SWITCH_HREF, + ) + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/zh_chapters/SUMMARY.md b/zh_chapters/SUMMARY.md new file mode 100644 index 0000000..49f4c38 --- /dev/null +++ b/zh_chapters/SUMMARY.md @@ -0,0 +1,110 @@ +# Summary + +[机器学习系统:设计和实现](index.md) +[前言](chapter_preface/index.md) + +# 基础篇 + +- [导论](chapter_introduction/index.md) + - [机器学习应用](chapter_introduction/applications.md) + - [机器学习框架的设计目标](chapter_introduction/design.md) + - [机器学习框架的基本组成原理](chapter_introduction/architecture.md) + - [机器学习系统生态](chapter_introduction/ecosystem.md) + - [图书结构和读者](chapter_introduction/readers.md) +- [编程接口](chapter_programming_interface/index.md) + - [机器学习系统编程模型的演进](chapter_programming_interface/development_history.md) + - [机器学习工作流](chapter_programming_interface/ml_workflow.md) + - [定义深度神经网络](chapter_programming_interface/neural_network_layer.md) + - [C/C++编程接口](chapter_programming_interface/c_python_interaction.md) + - [机器学习框架的编程范式](chapter_programming_interface/ml_programming_paradigm.md) + - [总结](chapter_programming_interface/summary.md) +- [计算图](chapter_computational_graph/index.md) + - [计算图的设计背景和作用](chapter_computational_graph/background_and_functionality.md) + - [计算图的基本构成](chapter_computational_graph/components_of_computational_graph.md) + - [计算图的生成](chapter_computational_graph/generation_of_computational_graph.md) + - [计算图的调度](chapter_computational_graph/schedule_of_computational_graph.md) + - [总结](chapter_computational_graph/summary.md) + +# 进阶篇 + +- [导读](chapter_preface_advanced/index.md) +- [AI编译器和前端技术](chapter_frontend_and_ir/index.md) + - [AI编译器设计原理](chapter_frontend_and_ir/ai_compiler_design_principle.md) + - [AI编译器前端技术概述](chapter_frontend_and_ir/overview_of_frontend.md) + - [中间表示](chapter_frontend_and_ir/intermediate_representation.md) + - [自动微分](chapter_frontend_and_ir/ad.md) + - [类型系统和静态分析](chapter_frontend_and_ir/type_system_and_static_analysis.md) + - [常见前端编译优化方法](chapter_frontend_and_ir/common_frontend_optimization_pass.md) + - [总结](chapter_frontend_and_ir/summary.md) +- [编译器后端和运行时](chapter_backend_and_runtime/index.md) + - [概述](chapter_backend_and_runtime/overview.md) + - [计算图优化](chapter_backend_and_runtime/graph_optimizer.md) + - [算子选择](chapter_backend_and_runtime/kernel_selecter.md) + - [内存分配](chapter_backend_and_runtime/memory_allocator.md) + - [计算调度与执行](chapter_backend_and_runtime/compute_schedule_and_execute.md) + - [算子编译器](chapter_backend_and_runtime/op_compiler.md) + - [总结](chapter_backend_and_runtime/summary.md) +- [硬件加速器](chapter_accelerator/index.md) + - [概述](chapter_accelerator/accelerator_introduction.md) + - [加速器基本组成原理](chapter_accelerator/accelerator_architecture.md) + - [加速器基本编程原理](chapter_accelerator/accelerator_programming.md) + - [加速器实践](chapter_accelerator/accelerator_practise.md) + - [总结](chapter_accelerator/summary.md) +- [数据处理框架](chapter_data_processing/index.md) + - [概述](chapter_data_processing/requirements.md) + - [易用性设计](chapter_data_processing/program_model.md) + - [高效性设计](chapter_data_processing/performance.md) + - [保序性设计](chapter_data_processing/data_order.md) + - [单机数据处理性能的扩展](chapter_data_processing/extension.md) + - [总结](chapter_data_processing/summary.md) +- [模型部署](chapter_model_deployment/index.md) + - [概述](chapter_model_deployment/model_deployment_introduction.md) + - [训练模型到推理模型的转换及优化](chapter_model_deployment/model_converter_and_optimizer.md) + - [模型压缩](chapter_model_deployment/model_compression.md) + - [模型推理](chapter_model_deployment/model_inference.md) + - [模型的安全保护](chapter_model_deployment/model_security.md) + - [总结](chapter_model_deployment/summary.md) +- [分布式训练](chapter_distributed_training/index.md) + - [系统概述](chapter_distributed_training/overview.md) + - [实现方法](chapter_distributed_training/methods.md) + - [机器学习集群架构](chapter_distributed_training/cluster.md) + - [集合通信](chapter_distributed_training/collective.md) + - [参数服务器](chapter_distributed_training/parameter_servers.md) + - [总结](chapter_distributed_training/summary.md) + +# 拓展篇 + +- [导读](chapter_preface_extension/index.md) +- [深度学习推荐系统](chapter_recommender_system/index.md) + - [系统基本组成](chapter_recommender_system/system_architecture.md) + - [多阶段推荐系统](chapter_recommender_system/multi_stage_recommender_system.md) + - [模型更新](chapter_recommender_system/model_update.md) + - [案例分析:支持在线模型更新的大型推荐系统](chapter_recommender_system/case_study.md) + - [小结](chapter_recommender_system/summary.md) +- [联邦学习系统](chapter_federated_learning/index.md) + - [概述](chapter_federated_learning/overview.md) + - [横向联邦学习](chapter_federated_learning/horizontal_fl.md) + - [纵向联邦学习](chapter_federated_learning/vertical_fl.md) + - [隐私加密算法](chapter_federated_learning/privacy_encryption_algorithm.md) + - [展望](chapter_federated_learning/outlook.md) + - [小结](chapter_federated_learning/summary.md) +- [强化学习系统](chapter_reinforcement_learning/index.md) + - [强化学习介绍](chapter_reinforcement_learning/rl_introduction.md) + - [单节点强化学习系统](chapter_reinforcement_learning/single_node_rl.md) + - [多智能体强化学习](chapter_reinforcement_learning/marl.md) + - [多智能体强化学习系统](chapter_reinforcement_learning/marl_sys.md) + - [小结](chapter_reinforcement_learning/summary.md) +- [可解释性AI系统](chapter_explainable_AI/index.md) + - [背景](chapter_explainable_AI/explainable_ai.md) +- [机器人系统](chapter_rl_sys/index.md) + - [机器人系统概述](chapter_rl_sys/rl_sys_intro.md) + - [通用机器人操作系统](chapter_rl_sys/ros.md) + - [案例分析:使用机器人操作系统](chapter_rl_sys/ros_code_ex.md) + - [总结](chapter_rl_sys/summary.md) + +# 附录 + +- [机器学习介绍](appendix_machine_learning_introduction/index.md) + - [神经网络](appendix_machine_learning_introduction/neural_network.md) + - [梯度下降与反向传播](appendix_machine_learning_introduction/gradient_descent.md) + - [经典机器学习方法](appendix_machine_learning_introduction/classic_machine_learning.md) diff --git a/zh_chapters/chapter_frontend_and_ir/intermediate_representation.md b/zh_chapters/chapter_frontend_and_ir/intermediate_representation.md index a549016..c6ce462 100644 --- a/zh_chapters/chapter_frontend_and_ir/intermediate_representation.md +++ b/zh_chapters/chapter_frontend_and_ir/intermediate_representation.md @@ -20,15 +20,11 @@ 上一节介绍了中间表示的基本概念,初步阐述了中间表示的重要作用和发展历程。接下来从组织结构的角度出发,介绍通用编译器的中间表示的类型以及各自特点 :cite:`2020MLIR`,如下表所示。中间表示组织结构的设计,对编译阶段的分析优化、代码生成等有着重要影响。编译器的设计需求不同,采用的中间表示组织结构也有所不同。 -::: {#tab:ch04/ch04-categorize} - 组织结构 特点 举例 - -------------- ---------------------- ---------------------------------- - Linear IR 基于线性代码 堆栈机代码、三地址代码 - Graphical IR 基于图 抽象语法树、有向无环图、控制流图 - Hybrid IR 基于图与线性代码混合 LLVM IR - - : 中间表示的分类 -::: +| 组织结构 | 特点 | 举例 | +|---|---|---| +| Linear IR | 基于线性代码 | 堆栈机代码、三地址代码 | +| Graphical IR | 基于图 | 抽象语法树、有向无环图、控制流图 | +| Hybrid IR | 基于图与线性代码混合 | LLVM IR | 1\) 线性中间表示 diff --git a/zh_chapters/chapter_model_deployment/model_converter_and_optimizer.md b/zh_chapters/chapter_model_deployment/model_converter_and_optimizer.md index 19cb181..f0d34c9 100644 --- a/zh_chapters/chapter_model_deployment/model_converter_and_optimizer.md +++ b/zh_chapters/chapter_model_deployment/model_converter_and_optimizer.md @@ -53,14 +53,10 @@ $$\pmb{Y_{bn}}=\pmb{A}*\pmb{X_{conv}}+\pmb{B}$$ 在融合过程中,Convolution计算公式和Batchnorm计算公式中被认为是常量的符号在训练时均为参数,并不是常量。训练阶段如果进行该融合会导致模型参数的缺失。从该融合Pattern的结果来看,融合后网络中减少了一个Batchnorm算子,减少了一个Batchnorm算子的参数量,其实就是改变了深度神经网络的算法,会影响到网络的准确率,这是不可接受的。所以Convolution算子与Batchnorm算子的融合一般是在部署阶段特有的一种优化手段,其优化效果以MindSpore Lite为例,构造了包含一个Convolution和一个Batchnorm的sample网络,分别以样例网络和mobilenet-v2网络为例,在华为Mate30手机上,以两线程运行模型推理,取3000轮推理的平均时耗作为模型推理性能的指标,对比融合前后该指标的变化。从表 :numref:`ch08-tab-conv_bn_fusion`可以看到,对于sample网络和mobilenet-v2网络,融合后分别获得了8.5%和11.7%的推理性能提升,这个性能提升非常可观。并且这个性能提升没有带来任何的副作用,也没有对于硬件或算子库的提出额外要求。 -::: {#tab:ch08-tab-conv_bn_fusion} - 网络 sample mobilenet-v2 - ------- ------------- ----------------- - 融合前 0.035 15.415 - 融合后 0.031 13.606 - -: Convolution + Batchnorm融合前后推理性能(单位:ms) -::: +| 网络 | sample | mobilenet-v2 | +|---|---|---| +| 融合前 | 0.035 | 15.415 | +| 融合后 | 0.031 | 13.606 | :label:`ch08-tab-conv_bn_fusion` ### 算子替换 diff --git a/zh_chapters/chapter_reinforcement_learning/index.md b/zh_chapters/chapter_reinforcement_learning/index.md index 5062091..318893a 100644 --- a/zh_chapters/chapter_reinforcement_learning/index.md +++ b/zh_chapters/chapter_reinforcement_learning/index.md @@ -13,7 +13,6 @@ rl_introduction single_node_rl -distributed_node_rl marl marl_sys summary diff --git a/zh_chapters/img b/zh_chapters/img deleted file mode 120000 index 0af1dd5..0000000 --- a/zh_chapters/img +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/img \ No newline at end of file diff --git a/zh_chapters/index.md b/zh_chapters/index.md index 737f631..fa3fa21 100644 --- a/zh_chapters/index.md +++ b/zh_chapters/index.md @@ -8,15 +8,16 @@ ```toc :maxdepth: 2 -:numbered: -chapter_preface/index +[前言](chapter_preface/index) + +# 基础篇 chapter_introduction/index chapter_programming_interface/index chapter_computational_graph/index -chapter_preface_advanced/index - +# 进阶篇 +[导读](chapter_preface_advanced/index) chapter_frontend_and_ir/index chapter_backend_and_runtime/index chapter_accelerator/index @@ -24,18 +25,14 @@ chapter_data_processing/index chapter_model_deployment/index chapter_distributed_training/index -chapter_preface_extension/index - +# 拓展篇 +[导读](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_machine_learning_introduction/index +# 附录 +[机器学习介绍](appendix_machine_learning_introduction/index) ``` diff --git a/zh_chapters/mlsys.bib b/zh_chapters/mlsys.bib deleted file mode 100644 index 9ed4432..0000000 --- a/zh_chapters/mlsys.bib +++ /dev/null @@ -1,1307 +0,0 @@ -@article{rosenblatt1958perceptron, - title={The perceptron: a probabilistic model for information storage and organization in the brain.}, - author={Rosenblatt, Frank}, - journal={Psychological Review}, - volume={65}, - number={6}, - pages={386}, - year={1958}, - publisher={American Psychological Association} -} - -@article{lecun1989backpropagation, - title={Backpropagation applied to handwritten zip code recognition}, - author={LeCun, Yann and Boser, Bernhard and Denker, John S and Henderson, Donnie and Howard, Richard E and Hubbard, Wayne and Jackel, Lawrence D}, - journal={Neural computation}, - volume={1}, - number={4}, - pages={541--551}, - year={1989}, - publisher={MIT Press} -} - -@article{lanctot2017unified, - title={A unified game-theoretic approach to multiagent reinforcement learning}, - author={Lanctot, Marc and Zambaldi, Vinicius and Gruslys, Audrunas and Lazaridou, Angeliki and Tuyls, Karl and P{\'e}rolat, Julien and Silver, David and Graepel, Thore}, - journal={Advances in neural information processing systems}, - volume={30}, - year={2017} -} - - -@article{mnih2013playing, - title={Playing atari with deep reinforcement learning}, - author={Mnih, Volodymyr and Kavukcuoglu, Koray and Silver, David and Graves, Alex and Antonoglou, Ioannis and Wierstra, Daan and Riedmiller, Martin}, - journal={arXiv preprint arXiv:1312.5602}, - year={2013} -} - -@article{sunehag2017value, - title={Value-decomposition networks for cooperative multi-agent learning}, - author={Sunehag, Peter and Lever, Guy and Gruslys, Audrunas and Czarnecki, Wojciech Marian and Zambaldi, Vinicius and Jaderberg, Max and Lanctot, Marc and Sonnerat, Nicolas and Leibo, Joel Z and Tuyls, Karl and others}, - journal={arXiv preprint arXiv:1706.05296}, - year={2017} -} - - -@inproceedings{rashid2018qmix, - title={Qmix: Monotonic value function factorisation for deep multi-agent reinforcement learning}, - author={Rashid, Tabish and Samvelyan, Mikayel and Schroeder, Christian and Farquhar, Gregory and Foerster, Jakob and Whiteson, Shimon}, - booktitle={International Conference on Machine Learning}, - pages={4295--4304}, - year={2018}, - organization={PMLR} -} - -@inproceedings{foerster2018counterfactual, - title={Counterfactual multi-agent policy gradients}, - author={Foerster, Jakob and Farquhar, Gregory and Afouras, Triantafyllos and Nardelli, Nantas and Whiteson, Shimon}, - booktitle={Proceedings of the AAAI conference on artificial intelligence}, - volume={32}, - number={1}, - year={2018} -} - - -@inproceedings{krizhevsky2012imagenet, - title={Imagenet classification with deep convolutional neural networks}, - author={Krizhevsky, Alex and Sutskever, Ilya and Hinton, Geoffrey E}, - booktitle={Advances in Neural Information Processing Systems}, - pages={1097--1105}, - year={2012} -} - -@inproceedings{he2016deep, - title={{Deep Residual Learning for Image Recognition}}, - author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian}, - booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, - year={2016} -} - -@article{rumelhart1986learning, - title={Learning representations by back-propagating errors}, - author={Rumelhart, David E and Hinton, Geoffrey E and Williams, Ronald J}, - journal={Nature}, - volume={323}, - number={6088}, - pages={533}, - year={1986}, - publisher={Nature Publishing Group} -} - -@article{Hochreiter1997lstm, - author = {Hochreiter, Sepp and Hochreiter, S and Schmidhuber, J{\"{u}}rgen and Schmidhuber, J}, - isbn = {08997667 (ISSN)}, - issn = {0899-7667}, - journal = {Neural Computation}, - number = {8}, - pages = {1735--80}, - pmid = {9377276}, - title = {{Long Short-Term Memory.}}, - volume = {9}, - year = {1997} -} - -@inproceedings{vaswani2017attention, - title={Attention is all you need}, - 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}, - booktitle={Advances in Neural Information Processing Systems}, - pages={5998--6008}, - year={2017} -} - -@article{lecun2015deep, - title={Deep learning}, - author={LeCun, Yann and Bengio, Yoshua and Hinton, Geoffrey}, - journal={Nature}, - volume={521}, - number={7553}, - pages={436}, - year={2015}, - publisher={Nature Publishing Group} -} - -@inproceedings{KingmaAdam2014, - title = {{Adam}: A Method for Stochastic Optimization}, - author = {Kingma, Diederik and Ba, Jimmy}, - booktitle = {Proceedings of the International Conference on Learning Representations (ICLR)}, - year = {2014} -} - -@techreport{tieleman2012rmsprop, - title={Divide the gradient by a running average of its recent magnitude. COURSERA: Neural networks for machine learning}, - author={Tieleman, T and Hinton, G}, - year={2017}, - institution={Technical Report} -} - -@article{duchi2011adagrad, - title={Adaptive subgradient methods for online learning and stochastic optimization}, - author={Duchi, John and Hazan, Elad and Singer, Yoram}, - journal={Journal of Machine Learning Research (JMLR)}, - volume={12}, - number={Jul}, - pages={2121--2159}, - year={2011} -} - -@inproceedings{meijer2006linq, - title={Linq: reconciling object, relations and xml in the. net framework}, - author={Meijer, Erik and Beckman, Brian and Bierman, Gavin}, - booktitle={Proceedings of the 2006 ACM SIGMOD international conference on Management of data}, - pages={706--706}, - year={2006} -} - -@inproceedings{murray2013naiad, - title={Naiad: a timely dataflow system}, - author={Murray, Derek G and McSherry, Frank and Isaacs, Rebecca and Isard, Michael and Barham, Paul and Abadi, Mart{\'\i}n}, - booktitle={Proceedings of the Twenty-Fourth ACM Symposium on Operating Systems Principles}, - pages={439--455}, - year={2013} -} - -@inproceedings{mnih2016asynchronous, - title={Asynchronous methods for deep reinforcement learning}, - author={Mnih, Volodymyr and Badia, Adria Puigdomenech and Mirza, Mehdi and Graves, Alex and Lillicrap, Timothy and Harley, Tim and Silver, David and Kavukcuoglu, Koray}, - booktitle={International Conference on Machine Learning (ICML)}, - pages={1928--1937}, - year={2016} -} - -@article{espeholt2018impala, - title={Impala: Scalable distributed deep-rl with importance weighted actor-learner architectures}, - author={Espeholt, Lasse and Soyer, Hubert and Munos, Remi and Simonyan, Karen and Mnih, Volodymir and Ward, Tom and Doron, Yotam and Firoiu, Vlad and Harley, Tim and Dunning, Iain and others}, - journal={arXiv preprint arXiv:1802.01561}, - year={2018} -} - -@article{espeholt2019seed, - title={Seed rl: Scalable and efficient deep-rl with accelerated central inference}, - author={Espeholt, Lasse and Marinier, Rapha{\"e}l and Stanczyk, Piotr and Wang, Ke and Michalski, Marcin}, - journal={arXiv preprint arXiv:1910.06591}, - year={2019} -} - -@misc{horgan2018distributed, - title={Distributed Prioritized Experience Replay}, - author={Dan Horgan and John Quan and David Budden and Gabriel Barth-Maron and Matteo Hessel and Hado van Hasselt and David Silver}, - year={2018}, - eprint={1803.00933}, - archivePrefix={arXiv}, - primaryClass={cs.LG} -} - -@inproceedings{moritz2018ray, - title={Ray: A distributed framework for emerging $\{$AI$\}$ applications}, - author={Moritz, Philipp and Nishihara, Robert and Wang, Stephanie and Tumanov, Alexey and Liaw, Richard and Liang, Eric and Elibol, Melih and Yang, Zongheng and Paul, William and Jordan, Michael I and others}, - booktitle={13th $\{$USENIX$\}$ Symposium on Operating Systems Design and Implementation ($\{$OSDI$\}$ 18)}, - pages={561--577}, - year={2018} -} - -@inproceedings{zaharia2010spark, - title={Spark: Cluster computing with working sets}, - author={Zaharia, Matei and Chowdhury, Mosharaf and Franklin, Michael J and Shenker, Scott and Stoica, Ion}, - booktitle={2nd USENIX Workshop on Hot Topics in Cloud Computing (HotCloud 10)}, - year={2010} -} - -@article{fetterly2009dryadlinq, - title={DryadLINQ: A system for general-purpose distributed data-parallel computing using a high-level language}, - author={Fetterly, Yuan Yu Michael Isard Dennis and Budiu, Mihai and Erlingsson, {\'U}lfar and Currey, Pradeep Kumar Gunda Jon}, - journal={Proc. LSDS-IR}, - volume={8}, - year={2009} -} - -@article{murray2021tf, - title={tf. data: A machine learning data processing framework}, - author={Murray, Derek G and Simsa, Jiri and Klimovic, Ana and Indyk, Ihor}, - journal={arXiv preprint arXiv:2101.12127}, - year={2021} -} - -@article{mohan2020analyzing, - title={Analyzing and mitigating data stalls in dnn training}, - author={Mohan, Jayashree and Phanishayee, Amar and Raniwala, Ashish and Chidambaram, Vijay}, - journal={arXiv preprint arXiv:2007.06775}, - year={2020} -} - -@misc{rmpygil - author = "Sam Gross", - title = "Multithreaded Python without the GIL", - howpublished = "Website", - year = {2021}, - note = {\url{https://docs.google.com/document/d/18CXhDb1ygxg-YXNBJNzfzZsDFosB5e6BfnXLlejd9l0/edit#heading=h.kcngwrty1lv}} -} - -@misc{nvidia_dali - author = "NVIDIA", - title = "DALI", - howpublished = "Website", - year = {2018}, - note = {\url{https://github.com/NVIDIA/DALI}} -} - -@misc{minddata - author = "HuaWei", - title = "Dataset Plugin", - howpublished = "Website", - year = {2020}, - note = {\url{https://gitee.com/mindspore/dataset-plugin}} -} - -@article{liang2017ray, - title={Ray rllib: A composable and scalable reinforcement learning library}, - author={Liang, Eric and Liaw, Richard and Nishihara, Robert and Moritz, Philipp and Fox, Roy and Gonzalez, Joseph and Goldberg, Ken and Stoica, Ion}, - journal={arXiv preprint arXiv:1712.09381}, - pages={85}, - year={2017} -} - -@article{cassirer2021reverb, - title={Reverb: A Framework For Experience Replay}, - author={Cassirer, Albin and Barth-Maron, Gabriel and Brevdo, Eugene and Ramos, Sabela and Boyd, Toby and Sottiaux, Thibault and Kroiss, Manuel}, - journal={arXiv preprint arXiv:2102.04736}, - year={2021} -} - -@article{hoffman2020acme, - title={Acme: A research framework for distributed reinforcement learning}, - author={Hoffman, Matt and Shahriari, Bobak and Aslanides, John and Barth-Maron, Gabriel and Behbahani, Feryal and Norman, Tamara and Abdolmaleki, Abbas and Cassirer, Albin and Yang, Fan and Baumli, Kate and others}, - journal={arXiv preprint arXiv:2006.00979}, - year={2020} -} - -@article{ding2020efficient, - title={Efficient Reinforcement Learning Development with RLzoo}, - author={Ding, Zihan and Yu, Tianyang and Huang, Yanhua and Zhang, Hongming and Li, Guo and Guo, Quancheng and Mai, Luo and Dong, Hao}, - journal={arXiv preprint arXiv:2009.08644}, - year={2020} -} - -@article{makoviychuk2021isaac, - title={Isaac Gym: High Performance GPU-Based Physics Simulation For Robot Learning}, - author={Makoviychuk, Viktor and Wawrzyniak, Lukasz and Guo, Yunrong and Lu, Michelle and Storey, Kier and Macklin, Miles and Hoeller, David and Rudin, Nikita and Allshire, Arthur and Handa, Ankur and others}, - journal={arXiv preprint arXiv:2108.10470}, - year={2021} -} - -@article{vinyals2019grandmaster, - title={Grandmaster level in StarCraft II using multi-agent reinforcement learning}, - author={Vinyals, Oriol and Babuschkin, Igor and Czarnecki, Wojciech M and Mathieu, Micha{\"e}l and Dudzik, Andrew and Chung, Junyoung and Choi, David H and Powell, Richard and Ewalds, Timo and Georgiev, Petko and others}, - journal={Nature}, - volume={575}, - number={7782}, - pages={350--354}, - year={2019}, - publisher={Nature Publishing Group} -} - -@article{berner2019dota, - title={Dota 2 with large scale deep reinforcement learning}, - author={Berner, Christopher and Brockman, Greg and Chan, Brooke and Cheung, Vicki and D{\k{e}}biak, Przemys{\l}aw and Dennison, Christy and Farhi, David and Fischer, Quirin and Hashme, Shariq and Hesse, Chris and others}, - journal={arXiv preprint arXiv:1912.06680}, - year={2019} -} - -@article{han2020tstarbot, - title={Tstarbot-x: An open-sourced and comprehensive study for efficient league training in starcraft ii full game}, - author={Han, Lei and Xiong, Jiechao and Sun, Peng and Sun, Xinghai and Fang, Meng and Guo, Qingwei and Chen, Qiaobo and Shi, Tengfei and Yu, Hongsheng and Wu, Xipeng and others}, - journal={arXiv preprint arXiv:2011.13729}, - year={2020} -} - -@inproceedings{wang2021scc, - title={SCC: an efficient deep reinforcement learning agent mastering the game of StarCraft II}, - author={Wang, Xiangjun and Song, Junxiao and Qi, Penghui and Peng, Peng and Tang, Zhenkun and Zhang, Wei and Li, Weimin and Pi, Xiongjun and He, Jujie and Gao, Chao and others}, - booktitle={International Conference on Machine Learning}, - pages={10905--10915}, - year={2021}, - organization={PMLR} -} - -@inproceedings{MLSYS2021_979d472a, - author = {Yin, Chunxing and Acun, Bilge and Wu, Carole-Jean and Liu, Xing}, - booktitle = {Proceedings of Machine Learning and Systems}, - editor = {A. Smola and A. Dimakis and I. Stoica}, - pages = {448--462}, - title = {TT-Rec: Tensor Train Compression for Deep Learning Recommendation Models}, - url = {https://proceedings.mlsys.org/paper/2021/file/979d472a84804b9f647bc185a877a8b5-Paper.pdf}, - volume = {3}, - year = {2021} -} - -@inproceedings{MLSYS2020_f7e6c855, - author = {Zhao, Weijie and Xie, Deping and Jia, Ronglai and Qian, Yulei and Ding, Ruiquan and Sun, Mingming and Li, Ping}, - booktitle = {Proceedings of Machine Learning and Systems}, - editor = {I. Dhillon and D. Papailiopoulos and V. Sze}, - pages = {412--428}, - title = {Distributed Hierarchical GPU Parameter Server for Massive Scale Deep Learning Ads Systems}, - url = {https://proceedings.mlsys.org/paper/2020/file/f7e6c85504ce6e82442c770f7c8606f0-Paper.pdf}, - volume = {2}, - year = {2020} -} - -@article{zionex, - title={Software-Hardware Co-design for Fast and Scalable Training of Deep Learning Recommendation Models}, - author={Mudigere, Dheevatsa and Hao, Yuchen and Huang, Jianyu and Jia, Zhihao and Tulloch, Andrew and Sridharan, Srinivas and Liu, Xing and Ozdal, Mustafa and Nie, Jade and Park, Jongsoo and others}, - journal={arXiv preprint arXiv:2104.05158}, - year={2021} -} - -@inproceedings{gong2020edgerec, - title={EdgeRec: Recommender System on Edge in Mobile Taobao}, - author={Gong, Yu and Jiang, Ziwen and Feng, Yufei and Hu, Binbin and Zhao, Kaiqi and Liu, Qingwen and Ou, Wenwu}, - booktitle={Proceedings of the 29th ACM International Conference on Information \& Knowledge Management}, - pages={2477--2484}, - year={2020} -} - -@inproceedings{NEURIPS2020_a1d4c20b, - author = {He, Chaoyang and Annavaram, Murali and Avestimehr, Salman}, - booktitle = {Advances in Neural Information Processing Systems}, - editor = {H. Larochelle and M. Ranzato and R. Hadsell and M. F. Balcan and H. Lin}, - pages = {14068--14080}, - publisher = {Curran Associates, Inc.}, - title = {Group Knowledge Transfer: Federated Learning of Large CNNs at the Edge}, - url = {https://proceedings.neurips.cc/paper/2020/file/a1d4c20b182ad7137ab3606f0e3fc8a4-Paper.pdf}, - volume = {33}, - year = {2020} -} - -@INPROCEEDINGS{9355295, - author={Xie, Minhui and Ren, Kai and Lu, Youyou and Yang, Guangxu and Xu, Qingxing and Wu, Bihai and Lin, Jiazhen and Ao, Hongbo and Xu, Wanhong and Shu, Jiwu}, - booktitle={SC20: International Conference for High Performance Computing, Networking, Storage and Analysis}, - title={Kraken: Memory-Efficient Continual Learning for Large-Scale Real-Time Recommendations}, - year={2020}, - volume={}, - number={}, - pages={1-17}, - doi={10.1109/SC41405.2020.00025} -} - -@inproceedings{MLSYS2021_ec895663, - author = {Jiang, Wenqi and He, Zhenhao and Zhang, Shuai and Preu\ss er, Thomas B. and Zeng, Kai and Feng, Liang and Zhang, Jiansong and Liu, Tongxuan and Li , Yong and Zhou, Jingren and Zhang, Ce and Alonso, Gustavo}, - booktitle = {Proceedings of Machine Learning and Systems}, - editor = {A. Smola and A. Dimakis and I. Stoica}, - pages = {845--859}, - title = {MicroRec: Efficient Recommendation Inference by Hardware and Data Structure Solutions}, - url = {https://proceedings.mlsys.org/paper/2021/file/ec8956637a99787bd197eacd77acce5e-Paper.pdf}, - volume = {3}, - year = {2021} -} - -@inproceedings{10.1145/3394486.3403059, -author = {Shi, Hao-Jun Michael and Mudigere, Dheevatsa and Naumov, Maxim and Yang, Jiyan}, -title = {Compositional Embeddings Using Complementary Partitions for Memory-Efficient Recommendation Systems}, -year = {2020}, -isbn = {9781450379984}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3394486.3403059}, -doi = {10.1145/3394486.3403059}, -abstract = {}, -booktitle = {Proceedings of the 26th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining}, -pages = {165–175}, -numpages = {11}, -keywords = {model compression, recommendation systems, embeddings}, -location = {Virtual Event, CA, USA}, -series = {KDD '20} -} - -@misc{ginart2021mixed, - title={Mixed Dimension Embeddings with Application to Memory-Efficient Recommendation Systems}, - author={Antonio Ginart and Maxim Naumov and Dheevatsa Mudigere and Jiyan Yang and James Zou}, - year={2021}, - eprint={1909.11810}, - archivePrefix={arXiv}, - primaryClass={cs.LG} -} - -@inproceedings{10.1145/2020408.2020444, -author = {Chu, Wei and Zinkevich, Martin and Li, Lihong and Thomas, Achint and Tseng, Belle}, -title = {Unbiased Online Active Learning in Data Streams}, -year = {2011}, -isbn = {9781450308137}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/2020408.2020444}, -doi = {10.1145/2020408.2020444}, -abstract = {Unlabeled samples can be intelligently selected for labeling to minimize classification error. In many real-world applications, a large number of unlabeled samples arrive in a streaming manner, making it impossible to maintain all the data in a candidate pool. In this work, we focus on binary classification problems and study selective labeling in data streams where a decision is required on each sample sequentially. We consider the unbiasedness property in the sampling process, and design optimal instrumental distributions to minimize the variance in the stochastic process. Meanwhile, Bayesian linear classifiers with weighted maximum likelihood are optimized online to estimate parameters. In empirical evaluation, we collect a data stream of user-generated comments on a commercial news portal in 30 consecutive days, and carry out offline evaluation to compare various sampling strategies, including unbiased active learning, biased variants, and random sampling. Experimental results verify the usefulness of online active learning, especially in the non-stationary situation with concept drift.}, -booktitle = {Proceedings of the 17th ACM SIGKDD International Conference on Knowledge Discovery and Data Mining}, -pages = {195–203}, -numpages = {9}, -keywords = {unbiasedness, bayesian online learning, active learning, data streaming, adaptive importance sampling}, -location = {San Diego, California, USA}, -series = {KDD '11} -} - -@inproceedings{10.1145/3267809.3267817, -author = {Tian, Huangshi and Yu, Minchen and Wang, Wei}, -title = {Continuum: A Platform for Cost-Aware, Low-Latency Continual Learning}, -year = {2018}, -isbn = {9781450360111}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3267809.3267817}, -doi = {10.1145/3267809.3267817}, -abstract = {Many machine learning applications operate in dynamic environments that change over time, in which models must be continually updated to capture the recent trend in data. However, most of today's learning frameworks perform training offline, without a system support for continual model updating.In this paper, we design and implement Continuum, a general-purpose platform that streamlines the implementation and deployment of continual model updating across existing learning frameworks. In pursuit of fast data incorporation, we further propose two update policies, cost-aware and best-effort, that judiciously determine when to perform model updating, with and without accounting for the training cost (machine-time), respectively. Theoretical analysis shows that cost-aware policy is 2-competitive. We implement both polices in Continuum, and evaluate their performance through EC2 deployment and trace-driven simulations. The evaluation shows that Continuum results in reduced data incorporation latency, lower training cost, and improved model quality in a number of popular online learning applications that span multiple application domains, programming languages, and frameworks.}, -booktitle = {Proceedings of the ACM Symposium on Cloud Computing}, -pages = {26–40}, -numpages = {15}, -keywords = {Competitive Analysis, Continual Learning System, Online Algorithm}, -location = {Carlsbad, CA, USA}, -series = {SoCC '18} -} - -@inproceedings{10.1145/2648584.2648589, -author = {He, Xinran and Pan, Junfeng and Jin, Ou and Xu, Tianbing and Liu, Bo and Xu, Tao and Shi, Yanxin and Atallah, Antoine and Herbrich, Ralf and Bowers, Stuart and Candela, Joaquin Qui\~{n}onero}, -title = {Practical Lessons from Predicting Clicks on Ads at Facebook}, -year = {2014}, -isbn = {9781450329996}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/2648584.2648589}, -doi = {10.1145/2648584.2648589}, -abstract = {Online advertising allows advertisers to only bid and pay for measurable user responses, such as clicks on ads. As a consequence, click prediction systems are central to most online advertising systems. With over 750 million daily active users and over 1 million active advertisers, predicting clicks on Facebook ads is a challenging machine learning task. In this paper we introduce a model which combines decision trees with logistic regression, outperforming either of these methods on its own by over 3%, an improvement with significant impact to the overall system performance. We then explore how a number of fundamental parameters impact the final prediction performance of our system. Not surprisingly, the most important thing is to have the right features: those capturing historical information about the user or ad dominate other types of features. Once we have the right features and the right model (decisions trees plus logistic regression), other factors play small roles (though even small improvements are important at scale). Picking the optimal handling for data freshness, learning rate schema and data sampling improve the model slightly, though much less than adding a high-value feature, or picking the right model to begin with.}, -booktitle = {Proceedings of the Eighth International Workshop on Data Mining for Online Advertising}, -pages = {1–9}, -numpages = {9}, -location = {New York, NY, USA}, -series = {ADKDD'14} -} - -@misc{2017NVIDIA, - author={NVIDIA}, - title={NVIDIA Tesla V100 GPU Architecture: The World's Most Advanced Datacenter GPU}, - year={2017}, - howpublished = "Website", - note = {\url{http://www.nvidia.com/object/volta-architecture-whitepaper.html}} -} - -@inproceedings{2021Ascend, - title={Ascend: a Scalable and Unified Architecture for Ubiquitous Deep Neural Network Computing : Industry Track Paper}, - author={Liao, Heng and Tu, Jiajin and Xia, Jing and Liu, Hu and Zhou, Xiping and Yuan, Honghui and Hu, Yuxing}, - booktitle={2021 IEEE International Symposium on High-Performance Computer Architecture (HPCA)}, - year={2021}, - pages = {789–801}, - doi = {10.1109/HPCA51647.2021.00071}, -} - -@article{2018Modeling, - title={Modeling Deep Learning Accelerator Enabled GPUs}, - author={Raihan, M. A. and Goli, N. and Aamodt, T.}, - journal={arXiv e-prints arXiv:1811.08309}, - year={2018} -} - -@book{2007Engineering, - title={Engineering a Compiler}, - author={ Cooper, Keith D. and Torczon, Linda }, - publisher={Engineering A Compiler}, - year={2007}, -} - -@article{ragan2013halide, - title={Halide: a language and compiler for optimizing parallelism, locality, and recomputation in image processing pipelines}, - author={Ragan-Kelley, Jonathan and Barnes, Connelly and Adams, Andrew and Paris, Sylvain and Durand, Fr{\'e}do and Amarasinghe, Saman}, - journal={Acm Sigplan Notices}, - volume={48}, - number={6}, - pages={519--530}, - year={2013}, - publisher={ACM New York, NY, USA} -} - -@inproceedings{verdoolaege2010isl, - title={isl: An integer set library for the polyhedral model}, - author={Verdoolaege, Sven}, - booktitle={International Congress on Mathematical Software}, - pages={299--302}, - year={2010}, - organization={Springer} -} - -@article{chen2018tvm, - title={TVM: end-to-end optimization stack for deep learning}, - author={Chen, Tianqi and Moreau, Thierry and Jiang, Ziheng and Shen, Haichen and Yan, Eddie Q and Wang, Leyuan and Hu, Yuwei and Ceze, Luis and Guestrin, Carlos and Krishnamurthy, Arvind}, - journal={arXiv preprint arXiv:1802.04799}, - volume={11}, - pages={20}, - year={2018}, - publisher={CoRR} -} - -@inproceedings{zheng2020ansor, - title={Ansor: Generating $\{$High-Performance$\}$ Tensor Programs for Deep Learning}, - author={Zheng, Lianmin and Jia, Chengfan and Sun, Minmin and Wu, Zhao and Yu, Cody Hao and Haj-Ali, Ameer and Wang, Yida and Yang, Jun and Zhuo, Danyang and Sen, Koushik and others}, - booktitle={14th USENIX Symposium on Operating Systems Design and Implementation (OSDI 20)}, - pages={863--879}, - year={2020} -} - -@inproceedings{zhao2021akg, - title={AKG: automatic kernel generation for neural processing units using polyhedral transformations}, - author={Zhao, Jie and Li, Bojie and Nie, Wang and Geng, Zhen and Zhang, Renwei and Gao, Xiong and Cheng, Bin and Wu, Chen and Cheng, Yun and Li, Zheng and others}, - booktitle={Proceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation}, - pages={1233--1248}, - year={2021} -} - -@article{lattner2020mlir, - title={MLIR: A compiler infrastructure for the end of Moore's law}, - author={Lattner, Chris and Amini, Mehdi and Bondhugula, Uday and Cohen, Albert and Davis, Andy and Pienaar, Jacques and Riddle, River and Shpeisman, Tatiana and Vasilache, Nicolas and Zinenko, Oleksandr}, - journal={arXiv preprint arXiv:2002.11054}, - year={2020} -} - -@article{vasilache2022composable, - title={Composable and Modular Code Generation in MLIR: A Structured and Retargetable Approach to Tensor Compiler Construction}, - author={Vasilache, Nicolas and Zinenko, Oleksandr and Bik, Aart JC and Ravishankar, Mahesh and Raoux, Thomas and Belyaev, Alexander and Springer, Matthias and Gysi, Tobias and Caballero, Diego and Herhut, Stephan and others}, - journal={arXiv preprint arXiv:2202.03293}, - year={2022} -} - -@inproceedings{bastoul2004code, - title={Code generation in the polyhedral model is easier than you think}, - author={Bastoul, C{\'e}dric}, - booktitle={Proceedings. 13th International Conference on Parallel Architecture and Compilation Techniques, 2004. PACT 2004.}, - pages={7--16}, - year={2004}, - organization={IEEE} -} - -@ARTICLE{2020tkde_li, - author={Li, Xiao-Hui and Cao, Caleb Chen and Shi, Yuhan and Bai, Wei and Gao, Han and Qiu, Luyu and Wang, Cong and Gao, Yuanyuan and Zhang, Shenjia and Xue, Xun and Chen, Lei}, - journal={IEEE Transactions on Knowledge and Data Engineering}, - title={A Survey of Data-driven and Knowledge-aware eXplainable AI}, - year={2020}, - volume={}, - number={}, - pages={1-1}, - doi={10.1109/TKDE.2020.2983930} -} - -@article{erhan2009visualizing, - title={Visualizing higher-layer features of a deep network}, - author={Erhan, Dumitru and Bengio, Yoshua and Courville, Aaron and Vincent, Pascal}, - journal={University of Montreal}, - volume={1341}, - number={3}, - pages={1}, - year={2009} -} - -@misc{kim2018interpretability, - title={Interpretability Beyond Feature Attribution: Quantitative Testing with Concept Activation Vectors (TCAV)}, - author={Been Kim and Martin Wattenberg and Justin Gilmer and Carrie Cai and James Wexler and Fernanda Viegas and Rory Sayres}, - year={2018}, - eprint={1711.11279}, - archivePrefix={arXiv}, - primaryClass={stat.ML} -} - -@article{riedl2019human, - title={Human-centered artificial intelligence and machine learning}, - author={Riedl, Mark O.}, - journal={Human Behavior and Emerging Technologies}, - volume={1}, - number={1}, - pages={33--36}, - year={2019}, - publisher={Wiley Online Library} - -} - -@inproceedings{10.1145/3460231.3474255, -author = {de Souza Pereira Moreira, Gabriel and Rabhi, Sara and Lee, Jeong Min and Ak, Ronay and Oldridge, Even}, -title = {Transformers4Rec: Bridging the Gap between NLP and Sequential / Session-Based Recommendation}, -year = {2021}, -isbn = {9781450384582}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3460231.3474255}, -doi = {10.1145/3460231.3474255}, -abstract = {}, -booktitle = {Fifteenth ACM Conference on Recommender Systems}, -pages = {143–153}, -numpages = {11}, -location = {Amsterdam, Netherlands}, -series = {RecSys '21} -} - -@inproceedings{10.1145/3124749.3124754, -author = {Wang, Ruoxi and Fu, Bin and Fu, Gang and Wang, Mingliang}, -title = {Deep & Cross Network for Ad Click Predictions}, -year = {2017}, -isbn = {9781450351942}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3124749.3124754}, -doi = {10.1145/3124749.3124754}, -abstract = {Feature engineering has been the key to the success of many prediction models. However, the process is nontrivial and often requires manual feature engineering or exhaustive searching. DNNs are able to automatically learn feature interactions; however, they generate all the interactions implicitly, and are not necessarily efficient in learning all types of cross features. In this paper, we propose the Deep & Cross Network (DCN) which keeps the benefits of a DNN model, and beyond that, it introduces a novel cross network that is more efficient in learning certain bounded-degree feature interactions. In particular, DCN explicitly applies feature crossing at each layer, requires no manual feature engineering, and adds negligible extra complexity to the DNN model. Our experimental results have demonstrated its superiority over the state-of-art algorithms on the CTR prediction dataset and dense classification dataset, in terms of both model accuracy and memory usage.}, -booktitle = {Proceedings of the ADKDD'17}, -articleno = {12}, -numpages = {7}, -keywords = {CTR Prediction, Deep Learning, Neural Networks, Feature Crossing}, -location = {Halifax, NS, Canada}, -series = {ADKDD'17} -} - -@inproceedings{ijcai2017-239, - author = {Huifeng Guo and Ruiming TANG and Yunming Ye and Zhenguo Li and Xiuqiang He}, - title = {DeepFM: A Factorization-Machine based Neural Network for CTR Prediction}, - booktitle = {Proceedings of the Twenty-Sixth International Joint Conference on - Artificial Intelligence, {IJCAI-17}}, - pages = {1725--1731}, - year = {2017}, - doi = {10.24963/ijcai.2017/239}, - url = {https://doi.org/10.24963/ijcai.2017/239}, -} - -@article{naumov2019deep, - title={Deep learning recommendation model for personalization and recommendation systems}, - author={Naumov, Maxim and Mudigere, Dheevatsa and Shi, Hao-Jun Michael and Huang, Jianyu and Sundaraman, Narayanan and Park, Jongsoo and Wang, Xiaodong and Gupta, Udit and Wu, Carole-Jean and Azzolini, Alisson G and others}, - journal={arXiv preprint arXiv:1906.00091}, - year={2019} -} - -@inproceedings{NIPS2015_86df7dcf, - author = {Sculley, D. and Holt, Gary and Golovin, Daniel and Davydov, Eugene and Phillips, Todd and Ebner, Dietmar and Chaudhary, Vinay and Young, Michael and Crespo, Jean-Fran\c{c}ois and Dennison, Dan}, - booktitle = {Advances in Neural Information Processing Systems}, - editor = {C. Cortes and N. Lawrence and D. Lee and M. Sugiyama and R. Garnett}, - pages = {}, - publisher = {Curran Associates, Inc.}, - title = {Hidden Technical Debt in Machine Learning Systems}, - url = {https://proceedings.neurips.cc/paper/2015/file/86df7dcfd896fcaf2674f757a2463eba-Paper.pdf}, - volume = {28}, - year = {2015} -} - -@misc{Merlin, - note={Accessed on 2022-03-24}, - author = {NVIDIA}, - year = {2022}, - title = {{{NVIDIA Merlin}}}, - howpublished = {\url{https://github.com/NVIDIA-Merlin/Merlin}}, -} - -@misc{NVTabular, - note={Accessed on 2022-03-24}, - author = {NVIDIA}, - year = {2022}, - title = {{{NVIDIA NVTabular}}}, - howpublished = {\url{https://github.com/NVIDIA-Merlin/NVTabular}}, -} - -@misc{HugeCTR, - note={Accessed on 2022-03-24}, - author = {NVIDIA}, - year = {2022}, - title = {{{NVIDIA HugeCTR}}}, - howpublished = {\url{https://github.com/NVIDIA-Merlin/HugeCTR}}, -} - -@misc{Triton, - note={Accessed on 2022-03-24}, - author = {NVIDIA}, - year = {2022}, - title = {{{NVIDIA Triton}}}, - howpublished = {\url{https://github.com/triton-inference-server/server}}, -} - -@inproceedings{10.1145/3437801.3441578, -author = {Fang, Jiarui and Yu, Yang and Zhao, Chengduo and Zhou, Jie}, -title = {TurboTransformers: An Efficient GPU Serving System for Transformer Models}, -year = {2021}, -isbn = {9781450382946}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3437801.3441578}, -doi = {10.1145/3437801.3441578}, -abstract = {The transformer is the most critical algorithm innovation of the Nature Language Processing (NLP) field in recent years. Unlike the Recurrent Neural Network (RNN) models, transformers are able to process on dimensions of sequence lengths in parallel, therefore leads to better accuracy on long sequences. However, efficient deployments of them for online services in data centers equipped with GPUs are not easy. First, more computation introduced by transformer structures makes it more challenging to meet the latency and throughput constraints of serving. Second, NLP tasks take in sentences of variable length. The variability of input dimensions brings a severe problem to efficient memory management and serving optimization.To solve the above challenges, this paper designed a transformer serving system called TurboTransformers, which consists of a computing runtime and a serving framework. Three innovative features make it stand out from other similar works. An efficient parallel algorithm is proposed for GPU-based batch reduction operations, like Softmax and LayerNorm, which are major hot spots besides BLAS routines. A memory allocation algorithm, which better balances the memory footprint and allocation/free efficiency, is designed for variable-length input situations. A serving framework equipped with a new batch scheduler using dynamic programming achieves the optimal throughput on variable-length requests. The system can achieve the state-of-the-art transformer model serving performance on GPU platforms and can be seamlessly integrated into your PyTorch code with a few lines of code.}, -booktitle = {Proceedings of the 26th ACM SIGPLAN Symposium on Principles and Practice of Parallel Programming}, -pages = {389–402}, -numpages = {14}, -keywords = {serving system, deep learning runtime, GPU, transformers}, -location = {Virtual Event, Republic of Korea}, -series = {PPoPP '21} -} - -@inproceedings{wang-etal-2021-lightseq, - title = "{L}ight{S}eq: A High Performance Inference Library for Transformers", - author = "Wang, Xiaohui and - Xiong, Ying and - Wei, Yang and - Wang, Mingxuan and - Li, Lei", - booktitle = "Proceedings of the 2021 Conference of the North American Chapter of the Association for Computational Linguistics: Human Language Technologies: Industry Papers", - month = jun, - year = "2021", - address = "Online", - publisher = "Association for Computational Linguistics", - url = "https://aclanthology.org/2021.naacl-industry.15", - doi = "10.18653/v1/2021.naacl-industry.15", - pages = "113--120", - abstract = "Transformer and its variants have achieved great success in natural language processing. Since Transformer models are huge in size, serving these models is a challenge for real industrial applications. In this paper, we propose , a highly efficient inference library for models in the Transformer family. includes a series of GPU optimization techniques to both streamline the computation of Transformer layers and reduce memory footprint. supports models trained using PyTorch and Tensorflow. Experimental results on standard machine translation benchmarks show that achieves up to 14x speedup compared with TensorFlow and 1.4x speedup compared with , a concurrent CUDA implementation. The code will be released publicly after the review.", -} - -@inproceedings{quigley2009ros, - title={ROS: an open-source Robot Operating System}, - author={Quigley, Morgan and Conley, Ken and Gerkey, Brian and Faust, Josh and Foote, Tully and Leibs, Jeremy and Wheeler, Rob and Ng, Andrew Y and others}, - booktitle={ICRA workshop on open source software}, - volume={3}, - number={3.2}, - pages={5}, - year={2009}, - organization={Kobe, Japan} -} - -@inproceedings{maruyama2016exploring, - title={Exploring the performance of ROS2}, - author={Maruyama, Yuya and Kato, Shinpei and Azumi, Takuya}, - booktitle={Proceedings of the 13th ACM SIGBED International Conference on Embedded Software (EMSOFT)}, - pages={1--10}, - year={2016} -} - -@inproceedings{ding2019camnet, - title={CamNet: Coarse-to-fine retrieval for camera re-localization}, - author={Ding, Mingyu and Wang, Zhe and Sun, Jiankai and Shi, Jianping and Luo, Ping}, - booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, - pages={2871--2880}, - year={2019} -} - -@inproceedings{yi2020segvoxelnet, - title={Segvoxelnet: Exploring semantic context and depth-aware features for 3d vehicle detection from point cloud}, - author={Yi, Hongwei and Shi, Shaoshuai and Ding, Mingyu and Sun, Jiankai and Xu, Kui and Zhou, Hui and Wang, Zhe and Li, Sheng and Wang, Guoping}, - booktitle={2020 IEEE International Conference on Robotics and Automation (ICRA)}, - pages={2274--2280}, - year={2020}, - organization={IEEE} -} - -@ARTICLE{9712373, author={Sun, Jiankai and Huang, De-An and Lu, Bo and Liu, Yun-Hui and Zhou, Bolei and Garg, Animesh}, journal={IEEE Robotics and Automation Letters}, title={PlaTe: Visually-Grounded Planning With Transformers in Procedural Tasks}, year={2022}, volume={7}, number={2}, pages={4924-4930}, doi={10.1109/LRA.2022.3150855}} - -@inproceedings{li2018undeepvo, - title={Undeepvo: Monocular visual odometry through unsupervised deep learning}, - author={Li, Ruihao and Wang, Sen and Long, Zhiqiang and Gu, Dongbing}, - booktitle={2018 IEEE international conference on robotics and automation (ICRA)}, - pages={7286--7291}, - year={2018}, - organization={IEEE} -} - -@inproceedings{quintero2021motion, - title={Motion planning via bayesian learning in the dark}, - author={Quintero-Pena, Carlos and Chamzas, Constantinos and Unhelkar, Vaibhav and Kavraki, Lydia E}, - booktitle={ICRA: Workshop on Machine Learning for Motion Planning}, - year={2021} -} - -@MISC{ML4KP, -author = {Edgar Granados and Aravind Sivaramakrishnan and Troy McMahon and Zakary Littlefield and Kostas E. Bekris}, -title = {Machine Learning for Kinodynamic Planning (ML4KP)}, -howpublished = {\url{https://github.com/PRX-Kinodynamic/ML4KP}}, -year = {2021--2021} -} - - - -@article{aradi2020survey, - title={Survey of deep reinforcement learning for motion planning of autonomous vehicles}, - author={Aradi, Szil{\'a}rd}, - journal={IEEE Transactions on Intelligent Transportation Systems}, - year={2020}, - publisher={IEEE} -} - -@article{vianna2021neural, - title={Neural Network Based Model Predictive Control for an Autonomous Vehicle}, - author={Vianna, Maria Luiza Costa and Goubault, Eric and Putot, Sylvie}, - journal={arXiv preprint arXiv:2107.14573}, - year={2021} -} - -@article{qiu2021egocentric, - title={Egocentric Human Trajectory Forecasting with a Wearable Camera and Multi-Modal Fusion}, - author={Qiu, Jianing and Chen, Lipeng and Gu, Xiao and Lo, Frank P-W and Tsai, Ya-Yen and Sun, Jiankai and Liu, Jiaqi and Lo, Benny}, - journal={arXiv preprint arXiv:2111.00993}, - year={2021} -} - -@InProceedings{pmlr-v155-huang21a, - title = {Learning a Decision Module by Imitating Driver’s Control Behaviors}, - author = {Huang, Junning and Xie, Sirui and Sun, Jiankai and Ma, Qiurui and Liu, Chunxiao and Lin, Dahua and Zhou, Bolei}, - booktitle = {Proceedings of the 2020 Conference on Robot Learning}, - pages = {1--10}, - year = {2021}, - editor = {Kober, Jens and Ramos, Fabio and Tomlin, Claire}, - volume = {155}, - series = {Proceedings of Machine Learning Research}, - month = {16--18 Nov}, - publisher = {PMLR}, - pdf = {https://proceedings.mlr.press/v155/huang21a/huang21a.pdf}, - url = {https://proceedings.mlr.press/v155/huang21a.html}, - abstract = {Autonomous driving systems have a pipeline of perception, decision, planning, and control. The decision module processes information from the perception module and directs the execution of downstream planning and control modules. On the other hand, the recent success of deep learning suggests that this pipeline could be replaced by end-to-end neural control policies, however, safety cannot be well guaranteed for the data-driven neural networks. In this work, we propose a hybrid framework to learn neural decisions in the classical modular pipeline through end-to-end imitation learning. This hybrid framework can preserve the merits of the classical pipeline such as the strict enforcement of physical and logical constraints while learning complex driving decisions from data. To circumvent the ambiguous annotation of human driving decisions, our method learns high-level driving decisions by imitating low-level control behaviors. We show in the simulation experiments that our modular driving agent can generalize its driving decision and control to various complex scenarios where the rule-based programs fail. It can also generate smoother and safer driving trajectories than end-to-end neural policies. Demo and code are available at https://decisionforce.github.io/modulardecision/.} -} - - -@InProceedings{pmlr-v155-sun21a, - title = {Neuro-Symbolic Program Search for Autonomous Driving Decision Module Design}, - author = {Sun, Jiankai and Sun, Hao and Han, Tian and Zhou, Bolei}, - booktitle = {Proceedings of the 2020 Conference on Robot Learning}, - pages = {21--30}, - year = {2021}, - editor = {Kober, Jens and Ramos, Fabio and Tomlin, Claire}, - volume = {155}, - series = {Proceedings of Machine Learning Research}, - month = {16--18 Nov}, - publisher = {PMLR}, - pdf = {https://proceedings.mlr.press/v155/sun21a/sun21a.pdf}, - url = {https://proceedings.mlr.press/v155/sun21a.html}, - abstract = {As a promising topic in cognitive robotics, neuro-symbolic modeling integrates symbolic reasoning and neural representation altogether. However, previous neuro-symbolic models usually wire their structures and the connections manually, making the underlying parameters sub-optimal. In this work, we propose the Neuro-Symbolic Program Search (NSPS) to improve the autonomous driving system design. NSPS is a novel automated search method that synthesizes the Neuro-Symbolic Programs. It can produce robust and expressive Neuro-Symbolic Programs and automatically tune the hyper-parameters. We validate NSPS in the CARLA driving simulation environment. The resulting Neuro-Symbolic Decision Programs successfully handle multiple traffic scenarios. Compared with previous neural-network-based driving and rule-based methods, our neuro-symbolic driving pipeline achieves more stable and safer behaviors in complex driving scenarios while maintaining an interpretable symbolic decision-making process.} -} - -@ARTICLE{9491826, author={Lu, Sidi and Shi, Weisong}, journal={IEEE Internet Computing}, title={The Emergence of Vehicle Computing}, year={2021}, volume={25}, number={3}, pages={18-22}, doi={10.1109/MIC.2021.3066076}} - -@article{benekohal1988carsim, - title={CARSIM: Car-following model for simulation of traffic in normal and stop-and-go conditions}, - author={Benekohal, Rahim F and Treiterer, Joseph}, - journal={Transportation research record}, - volume={1194}, - pages={99--111}, - year={1988}, - publisher={SAGE Publishing} -} - -@book{buehler2009darpa, - title={The DARPA urban challenge: autonomous vehicles in city traffic}, - author={Buehler, Martin and Iagnemma, Karl and Singh, Sanjiv}, - volume={56}, - year={2009}, - publisher={springer} -} - - -@InProceedings{pmlr-v100-bansal20a, - title = {Combining Optimal Control and Learning for Visual Navigation in Novel Environments}, - author = {Bansal, Somil and Tolani, Varun and Gupta, Saurabh and Malik, Jitendra and Tomlin, Claire}, - booktitle = {Proceedings of the Conference on Robot Learning}, - pages = {420--429}, - year = {2020}, - editor = {Kaelbling, Leslie Pack and Kragic, Danica and Sugiura, Komei}, - volume = {100}, - series = {Proceedings of Machine Learning Research}, - month = {30 Oct--01 Nov}, - publisher = {PMLR}, - pdf = {http://proceedings.mlr.press/v100/bansal20a/bansal20a.pdf}, - url = {https://proceedings.mlr.press/v100/bansal20a.html}, - abstract = {Model-based control is a popular paradigm for robot navigation because it can leverage a known dynamics model to efficiently plan robust robot trajectories. However, it is challenging to use model-based methods in settings where the environment is a priori unknown and can only be observed partially through onboard sensors on the robot. In this work, we address this short-coming by coupling model-based control with learning-based perception. The learning-based perception module produces a series of waypoints that guide the robot to the goal via a collision-free path. These waypoints are used by a model-based planner to generate a smooth and dynamically feasible trajectory that is executed on the physical system using feedback control. Our experiments in simulated real-world cluttered environments and on an actual ground vehicle demonstrate that the proposed approach can reach goal locations more reliably and efficiently in novel environments as compared to purely geometric mapping-based or end-to-end learning-based alternatives. Our approach does not rely on detailed explicit 3D maps of the environment, works well with low frame rates, and generalizes well from simulation to the real world. Videos describing our approach and experiments are available on the project website4.} -} - -@article{levine2018learning, - title={Learning hand-eye coordination for robotic grasping with deep learning and large-scale data collection}, - author={Levine, Sergey and Pastor, Peter and Krizhevsky, Alex and Ibarz, Julian and Quillen, Deirdre}, - journal={The International journal of robotics research}, - volume={37}, - number={4-5}, - pages={421--436}, - year={2018}, - publisher={SAGE Publications Sage UK: London, England} -} - -@incollection{peters2016robot, - title={Robot learning}, - author={Peters, Jan and Lee, Daniel D and Kober, Jens and Nguyen-Tuong, Duy and Bagnell, J Andrew and Schaal, Stefan}, - booktitle={Springer Handbook of Robotics}, - pages={357--398}, - year={2016}, - publisher={Springer} -} - -@article{saxena2014robobrain, - title={Robobrain: Large-scale knowledge engine for robots}, - author={Saxena, Ashutosh and Jain, Ashesh and Sener, Ozan and Jami, Aditya and Misra, Dipendra K and Koppula, Hema S}, - journal={arXiv preprint arXiv:1412.0691}, - year={2014} -} - -@inproceedings{zhu2017target, - title={Target-driven visual navigation in indoor scenes using deep reinforcement learning}, - author={Zhu, Yuke and Mottaghi, Roozbeh and Kolve, Eric and Lim, Joseph J and Gupta, Abhinav and Fei-Fei, Li and Farhadi, Ali}, - booktitle={2017 IEEE international conference on robotics and automation (ICRA)}, - pages={3357--3364}, - year={2017}, - organization={IEEE} -} - -@ARTICLE{9123682, author={Pan, Bowen and Sun, Jiankai and Leung, Ho Yin Tiga and Andonian, Alex and Zhou, Bolei}, journal={IEEE Robotics and Automation Letters}, title={Cross-View Semantic Segmentation for Sensing Surroundings}, year={2020}, volume={5}, number={3}, pages={4867-4873}, doi={10.1109/LRA.2020.3004325}} - -@article{tang2018ba, - title={Ba-net: Dense bundle adjustment network}, - author={Tang, Chengzhou and Tan, Ping}, - journal={arXiv preprint arXiv:1806.04807}, - year={2018} -} - -@inproceedings{tanaka2021learning, - title={Learning To Bundle-Adjust: A Graph Network Approach to Faster Optimization of Bundle Adjustment for Vehicular SLAM}, - author={Tanaka, Tetsuya and Sasagawa, Yukihiro and Okatani, Takayuki}, - booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, - pages={6250--6259}, - year={2021} -} - -@inproceedings{tobin2017domain, - title={Domain randomization for transferring deep neural networks from simulation to the real world}, - author={Tobin, Josh and Fong, Rachel and Ray, Alex and Schneider, Jonas and Zaremba, Wojciech and Abbeel, Pieter}, - booktitle={2017 IEEE/RSJ international conference on intelligent robots and systems (IROS)}, - pages={23--30}, - year={2017}, - organization={IEEE} -} - -@inproceedings{finn2017deep, - title={Deep visual foresight for planning robot motion}, - author={Finn, Chelsea and Levine, Sergey}, - booktitle={2017 IEEE International Conference on Robotics and Automation (ICRA)}, - pages={2786--2793}, - year={2017}, - organization={IEEE} -} - -@article{duan2017one, - title={One-shot imitation learning}, - author={Duan, Yan and Andrychowicz, Marcin and Stadie, Bradly and Jonathan Ho, OpenAI and Schneider, Jonas and Sutskever, Ilya and Abbeel, Pieter and Zaremba, Wojciech}, - journal={Advances in neural information processing systems}, - volume={30}, - year={2017} -} - -@book{koubaa2017robot, - title={Robot Operating System (ROS).}, - author={Koub{\^a}a, Anis and others}, - volume={1}, - year={2017}, - publisher={Springer} -} - -@article{coleman2014reducing, - title={Reducing the barrier to entry of complex robotic software: a moveit! case study}, - author={Coleman, David and Sucan, Ioan and Chitta, Sachin and Correll, Nikolaus}, - journal={arXiv preprint arXiv:1404.3785}, - year={2014} -} - -@inproceedings{salzmann2020trajectron++, - title={Trajectron++: Dynamically-feasible trajectory forecasting with heterogeneous data}, - author={Salzmann, Tim and Ivanovic, Boris and Chakravarty, Punarjay and Pavone, Marco}, - booktitle={European Conference on Computer Vision}, - pages={683--700}, - year={2020}, - organization={Springer} -} - -@inproceedings{gog2021pylot, - title={Pylot: A modular platform for exploring latency-accuracy tradeoffs in autonomous vehicles}, - author={Gog, Ionel and Kalra, Sukrit and Schafhalter, Peter and Wright, Matthew A and Gonzalez, Joseph E and Stoica, Ion}, - booktitle={2021 IEEE International Conference on Robotics and Automation (ICRA)}, - pages={8806--8813}, - year={2021}, - organization={IEEE} -} - -@inproceedings{Dosovitskiy17, - title = { {CARLA}: {An} Open Urban Driving Simulator}, - author = {Alexey Dosovitskiy and German Ros and Felipe Codevilla and Antonio Lopez and Vladlen Koltun}, - booktitle = {Proceedings of the 1st Annual Conference on Robot Learning}, - pages = {1--16}, - year = {2017} -} - -@inproceedings{10.1145/3492321.3519576, -author = {Gog, Ionel and Kalra, Sukrit and Schafhalter, Peter and Gonzalez, Joseph E. and Stoica, Ion}, -title = {D3: A Dynamic Deadline-Driven Approach for Building Autonomous Vehicles}, -year = {2022}, -isbn = {9781450391627}, -publisher = {Association for Computing Machinery}, -address = {New York, NY, USA}, -url = {https://doi.org/10.1145/3492321.3519576}, -doi = {10.1145/3492321.3519576}, -abstract = {Autonomous vehicles (AVs) must drive across a variety of challenging environments that impose continuously-varying deadlines and runtime-accuracy tradeoffs on their software pipelines. A deadline-driven execution of such AV pipelines requires a new class of systems that enable the computation to maximize accuracy under dynamically-varying deadlines. Designing these systems presents interesting challenges that arise from combining ease-of-development of AV pipelines with deadline specification and enforcement mechanisms.Our work addresses these challenges through D3 (Dynamic Deadline-Driven), a novel execution model that centralizes the deadline management, and allows applications to adjust their computation by modeling missed deadlines as exceptions. Further, we design and implement ERDOS, an open-source realization of D3 for AV pipelines that exposes finegrained execution events to applications, and provides mechanisms to speculatively execute computation and enforce deadlines between an arbitrary set of events. Finally, we address the crucial lack of AV benchmarks through our state-of-the-art open-source AV pipeline, Pylot, that works seamlessly across simulators and real AVs. We evaluate the efficacy of D3 and ERDOS by driving Pylot across challenging driving scenarios spanning 50km, and observe a 68% reduction in collisions as compared to prior execution models.}, -booktitle = {Proceedings of the Seventeenth European Conference on Computer Systems}, -pages = {453–471}, -numpages = {19}, -location = {Rennes, France}, -series = {EuroSys '22} -} - -@article{li2021metadrive, - author = {Li, Quanyi and Peng, Zhenghao and Xue, Zhenghai and Zhang, Qihang and Zhou, Bolei}, - journal = {ArXiv preprint}, - title = {Metadrive: Composing diverse driving scenarios for generalizable reinforcement learning}, - url = {https://arxiv.org/abs/2109.12674}, - volume = {abs/2109.12674}, - year = {2021} -} - -@article{peng2021learning, - author = {Peng, Zhenghao and Li, Quanyi and Hui, Ka Ming and Liu, Chunxiao and Zhou, Bolei}, - journal = {Advances in Neural Information Processing Systems}, - title = {Learning to Simulate Self-Driven Particles System with Coordinated Policy Optimization}, - volume = {34}, - year = {2021} -} - - -@inproceedings{peng2021safe, - author = {Peng, Zhenghao and Li, Quanyi and Liu, Chunxiao and Zhou, Bolei}, - booktitle = {5th Annual Conference on Robot Learning}, - title = {Safe Driving via Expert Guided Policy Optimization}, - year = {2021} -} - -@ARTICLE{8421746, author={Qin, Tong and Li, Peiliang and Shen, Shaojie}, journal={IEEE Transactions on Robotics}, title={VINS-Mono: A Robust and Versatile Monocular Visual-Inertial State Estimator}, year={2018}, volume={34}, number={4}, pages={1004-1020}, doi={10.1109/TRO.2018.2853729}} - -@article{campos2021orb, - title={Orb-slam3: An accurate open-source library for visual, visual--inertial, and multimap slam}, - author={Campos, Carlos and Elvira, Richard and Rodr{\'\i}guez, Juan J G{\'o}mez and Montiel, Jos{\'e} MM and Tard{\'o}s, Juan D}, - journal={IEEE Transactions on Robotics}, - volume={37}, - number={6}, - pages={1874--1890}, - year={2021}, - publisher={IEEE} -} - -@inproceedings{li2021efficient, - author = {Li, Quanyi and Peng, Zhenghao and Zhou, Bolei}, - booktitle = {International Conference on Learning Representations}, - title = {Efficient Learning of Safe Driving Policy via Human-AI Copilot Optimization}, - year = {2021} -} - -@article{chaplot2020learning, - title={Learning to explore using active neural slam}, - author={Chaplot, Devendra Singh and Gandhi, Dhiraj and Gupta, Saurabh and Gupta, Abhinav and Salakhutdinov, Ruslan}, - journal={arXiv preprint arXiv:2004.05155}, - year={2020} -} - -@article{teed2021droid, - title={Droid-slam: Deep visual slam for monocular, stereo, and rgb-d cameras}, - author={Teed, Zachary and Deng, Jia}, - journal={Advances in Neural Information Processing Systems}, - volume={34}, - year={2021} -} - -@article{brunke2021safe, - title={Safe learning in robotics: From learning-based control to safe reinforcement learning}, - author={Brunke, Lukas and Greeff, Melissa and Hall, Adam W and Yuan, Zhaocong and Zhou, Siqi and Panerati, Jacopo and Schoellig, Angela P}, - journal={Annual Review of Control, Robotics, and Autonomous Systems}, - volume={5}, - year={2021}, - publisher={Annual Reviews} -} - - -@InProceedings{pmlr-v144-gama21a, - title = {Graph Neural Networks for Distributed Linear-Quadratic Control}, - author = {Gama, Fernando and Sojoudi, Somayeh}, - booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control}, - pages = {111--124}, - year = {2021}, - editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.}, - volume = {144}, - series = {Proceedings of Machine Learning Research}, - month = {07 -- 08 June}, - publisher = {PMLR}, - pdf = {http://proceedings.mlr.press/v144/gama21a/gama21a.pdf}, - url = {https://proceedings.mlr.press/v144/gama21a.html}, - abstract = {The linear-quadratic controller is one of the fundamental problems in control theory. The optimal solution is a linear controller that requires access to the state of the entire system at any given time. When considering a network system, this renders the optimal controller a centralized one. The interconnected nature of a network system often demands a distributed controller, where different components of the system are controlled based only on local information. Unlike the classical centralized case, obtaining the optimal distributed controller is usually an intractable problem. Thus, we adopt a graph neural network (GNN) as a parametrization of distributed controllers. GNNs are naturally local and have distributed architectures, making them well suited for learning nonlinear distributed controllers. By casting the linear-quadratic problem as a self-supervised learning problem, we are able to find the best GNN-based distributed controller. We also derive sufficient conditions for the resulting closed-loop system to be stable. We run extensive simulations to study the performance of GNN-based distributed controllers and showcase that they are a computationally efficient parametrization with scalability and transferability capabilities.} -} - - -@InProceedings{pmlr-v144-mehrjou21a, - title = {Neural Lyapunov Redesign}, - author = {Mehrjou, Arash and Ghavamzadeh, Mohammad and Sch\"olkopf, Bernhard}, - booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control}, - pages = {459--470}, - year = {2021}, - editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.}, - volume = {144}, - series = {Proceedings of Machine Learning Research}, - month = {07 -- 08 June}, - publisher = {PMLR}, - pdf = {http://proceedings.mlr.press/v144/mehrjou21a/mehrjou21a.pdf}, - url = {https://proceedings.mlr.press/v144/mehrjou21a.html}, - abstract = {Learning controllers merely based on a performance metric has been proven effective in many physical and non-physical tasks in both control theory and reinforcement learning. However, in practice, the controller must guarantee some notion of safety to ensure that it does not harm either the agent or the environment. Stability is a crucial notion of safety, whose violation can certainly cause unsafe behaviors. Lyapunov functions are effective tools to assess stability in nonlinear dynamical systems. In this paper, we combine an improving Lyapunov function with automatic controller synthesis in an iterative fashion to obtain control policies with large safe regions. We propose a two-player collaborative algorithm that alternates between estimating a Lyapunov function and deriving a controller that gradually enlarges the stability region of the closed-loop system. We provide theoretical results on the class of systems that can be treated with the proposed algorithm and empirically evaluate the effectiveness of our method using an exemplary dynamical system.} -} - - -@InProceedings{pmlr-v144-zhang21b, - title = {{LEOC}: A Principled Method in Integrating Reinforcement Learning and Classical Control Theory}, - author = {Zhang, Naifu and Capel, Nicholas}, - booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control}, - pages = {689--701}, - year = {2021}, - editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.}, - volume = {144}, - series = {Proceedings of Machine Learning Research}, - month = {07 -- 08 June}, - publisher = {PMLR}, - pdf = {http://proceedings.mlr.press/v144/zhang21b/zhang21b.pdf}, - url = {https://proceedings.mlr.press/v144/zhang21b.html}, - abstract = {There have been attempts in reinforcement learning to exploit a priori knowledge about the structure of the system. This paper proposes a hybrid reinforcement learning controller which dynamically interpolates a model-based linear controller and an arbitrary differentiable policy. The linear controller is designed based on local linearised model knowledge, and stabilises the system in a neighbourhood about an operating point. The coefficients of interpolation between the two controllers are determined by a scaled distance function measuring the distance between the current state and the operating point. The overall hybrid controller is proven to maintain the stability guarantee around the neighborhood of the operating point and still possess the universal function approximation property of the arbitrary non-linear policy. Learning has been done on both model-based (PILCO) and model-free (DDPG) frameworks. Simulation experiments performed in OpenAI gym demonstrate stability and robustness of the proposed hybrid controller. This paper thus introduces a principled method allowing for the direct importing of control methodology into reinforcement learning.} -} - - -@InProceedings{pmlr-v144-rafailov21a, - title = {Offline Reinforcement Learning from Images with Latent Space Models}, - author = {Rafailov, Rafael and Yu, Tianhe and Rajeswaran, Aravind and Finn, Chelsea}, - booktitle = {Proceedings of the 3rd Conference on Learning for Dynamics and Control}, - pages = {1154--1168}, - year = {2021}, - editor = {Jadbabaie, Ali and Lygeros, John and Pappas, George J. and A. Parrilo, Pablo and Recht, Benjamin and Tomlin, Claire J. and Zeilinger, Melanie N.}, - volume = {144}, - series = {Proceedings of Machine Learning Research}, - month = {07 -- 08 June}, - publisher = {PMLR}, - pdf = {http://proceedings.mlr.press/v144/rafailov21a/rafailov21a.pdf}, - url = {https://proceedings.mlr.press/v144/rafailov21a.html}, - abstract = {Offline reinforcement learning (RL) refers to the task of learning policies from a static dataset of environment interactions. Offline RL enables extensive utilization and re-use of historical datasets, while also alleviating safety concerns associated with online exploration, thereby expanding the real-world applicability of RL. Most prior work in offline RL has focused on tasks with compact state representations. However, the ability to learn directly from rich observation spaces like images is critical for real-world applications like robotics. In this work, we build on recent advances in model-based algorithms for offline RL, and extend them to high-dimensional visual observation spaces. Model-based offline RL algorithms have achieved state of the art results in state based tasks and are minimax optimal. However, they rely crucially on the ability to quantify uncertainty in the model predictions. This is particularly challenging with image observations. To overcome this challenge, we propose to learn a latent-state dynamics model, and represent the uncertainty in the latent space. Our approach is both tractable in practice and corresponds to maximizing a lower bound of the ELBO in the unknown POMDP. Through experiments on a range of challenging image-based locomotion and robotic manipulation tasks, we find that our algorithm significantly outperforms previous offline model-free RL methods as well as state-of-the-art online visual model-based RL methods. Moreover, we also find that our approach excels on an image-based drawer closing task on a real robot using a pre-existing dataset. All results including videos can be found online at \url{https://sites.google.com/view/lompo/}.} -} - -@inproceedings{chen2020transferable, - title={Transferable active grasping and real embodied dataset}, - author={Chen, Xiangyu and Ye, Zelin and Sun, Jiankai and Fan, Yuda and Hu, Fang and Wang, Chenxi and Lu, Cewu}, - booktitle={2020 IEEE International Conference on Robotics and Automation (ICRA)}, - pages={3611--3618}, - year={2020}, - organization={IEEE} -} - -@article{sun2021adversarial, - title={Adversarial inverse reinforcement learning with self-attention dynamics model}, - author={Sun, Jiankai and Yu, Lantao and Dong, Pinqian and Lu, Bo and Zhou, Bolei}, - journal={IEEE Robotics and Automation Letters}, - volume={6}, - number={2}, - pages={1880--1886}, - year={2021}, - publisher={IEEE} -} - -@article{huang2018navigationnet, - title={NavigationNet: A large-scale interactive indoor navigation dataset}, - author={Huang, He and Shen, Yujing and Sun, Jiankai and Lu, Cewu}, - journal={arXiv preprint arXiv:1808.08374}, - year={2018} -} - -@inproceedings{xu2019depth, - title={Depth completion from sparse lidar data with depth-normal constraints}, - author={Xu, Yan and Zhu, Xinge and Shi, Jianping and Zhang, Guofeng and Bao, Hujun and Li, Hongsheng}, - booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, - pages={2811--2820}, - year={2019} -} - -@inproceedings{zhu2020ssn, - title={Ssn: Shape signature networks for multi-class object detection from point clouds}, - author={Zhu, Xinge and Ma, Yuexin and Wang, Tai and Xu, Yan and Shi, Jianping and Lin, Dahua}, - booktitle={European Conference on Computer Vision}, - pages={581--597}, - year={2020}, - organization={Springer} -} - -@inproceedings{huang2019prior, - title={Prior guided dropout for robust visual localization in dynamic environments}, - author={Huang, Zhaoyang and Xu, Yan and Shi, Jianping and Zhou, Xiaowei and Bao, Hujun and Zhang, Guofeng}, - booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision}, - pages={2791--2800}, - year={2019} -} - -@article{xu2020selfvoxelo, - title={Selfvoxelo: Self-supervised lidar odometry with voxel-based deep neural networks}, - author={Xu, Yan and Huang, Zhaoyang and Lin, Kwan-Yee and Zhu, Xinge and Shi, Jianping and Bao, Hujun and Zhang, Guofeng and Li, Hongsheng}, - journal={arXiv preprint arXiv:2010.09343}, - year={2020} -} - -@article{huang2021life, - title={LIFE: Lighting Invariant Flow Estimation}, - author={Huang, Zhaoyang and Pan, Xiaokun and Xu, Runsen and Xu, Yan and Zhang, Guofeng and Li, Hongsheng and others}, - journal={arXiv preprint arXiv:2104.03097}, - year={2021} -} - -@inproceedings{huang2021vs, - title={VS-Net: Voting with Segmentation for Visual Localization}, - author={Huang, Zhaoyang and Zhou, Han and Li, Yijin and Yang, Bangbang and Xu, Yan and Zhou, Xiaowei and Bao, Hujun and Zhang, Guofeng and Li, Hongsheng}, - booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition}, - pages={6101--6111}, - year={2021} -} - -@article{yang2021pdnet, - title={PDNet: Towards Better One-stage Object Detection with Prediction Decoupling}, - author={Yang, Li and Xu, Yan and Wang, Shaoru and Yuan, Chunfeng and Zhang, Ziqi and Li, Bing and Hu, Weiming}, - journal={arXiv preprint arXiv:2104.13876}, - year={2021} -} - -@article{xu2022robust, - title={Robust Self-supervised LiDAR Odometry via Representative Structure Discovery and 3D Inherent Error Modeling}, - author={Xu, Yan and Lin, Junyi and Shi, Jianping and Zhang, Guofeng and Wang, Xiaogang and Li, Hongsheng}, - journal={IEEE Robotics and Automation Letters}, - year={2022}, - publisher={IEEE} -} - -@article{xu2022rnnpose, - title={RNNPose: Recurrent 6-DoF Object Pose Refinement with Robust Correspondence Field Estimation and Pose Optimization}, - author={Xu, Yan and Lin, Junyi and Zhang, Guofeng and Wang, Xiaogang and Li, Hongsheng}, - journal={arXiv preprint arXiv:2203.12870}, - year={2022} -} - -@article{Sun2022SelfSupervisedTA, - title={Self-Supervised Traffic Advisors: Distributed, Multi-view Traffic Prediction for Smart Cities}, - author={Jiankai Sun and Shreyas Kousik and David Fridovich-Keil and Mac Schwager}, - journal={arXiv preprint}, - year={2022} -} - -@ARTICLE{9813561, author={Qiu, Jianing and Chen, Lipeng and Gu, Xiao and Lo, Frank P.-W. and Tsai, Ya-Yen and Sun, Jiankai and Liu, Jiaqi and Lo, Benny}, journal={IEEE Robotics and Automation Letters}, title={Egocentric Human Trajectory Forecasting with a Wearable Camera and Multi-Modal Fusion}, year={2022}, volume={}, number={}, pages={1-8}, doi={10.1109/LRA.2022.3188101}} - -@article{MegBA, - title={MegBA: A High-Performance and Distributed Library for Large-Scale Bundle Adjustment}, - author={Ren, Jie and Liang, Wenteng and Yan, Ran and Mai, Luo and Liu, Shiwen and Liu, Xiao}, - journal={European Conference on Computer Vision}, - year={2022} -} - -@inproceedings{li2023behavior, - title={Behavior-1k: A benchmark for embodied ai with 1,000 everyday activities and realistic simulation}, - author={Li, Chengshu and Zhang, Ruohan and Wong, Josiah and Gokmen, Cem and Srivastava, Sanjana and Mart{\'\i}n-Mart{\'\i}n, Roberto and Wang, Chen and Levine, Gabrael and Lingelbach, Michael and Sun, Jiankai and others}, - booktitle={Conference on Robot Learning}, - pages={80--93}, - year={2023}, - organization={PMLR} -} - -@article{wang2023mimicplay, - title={MimicPlay: Long-Horizon Imitation Learning by Watching Human Play}, - author={Wang, Chen and Fan, Linxi and Sun, Jiankai and Zhang, Ruohan and Fei-Fei, Li and Xu, Danfei and Zhu, Yuke and Anandkumar, Anima}, - journal={arXiv preprint arXiv:2302.12422}, - year={2023} -} diff --git a/zh_chapters/mlsys.bib b/zh_chapters/mlsys.bib new file mode 120000 index 0000000..ee7c463 --- /dev/null +++ b/zh_chapters/mlsys.bib @@ -0,0 +1 @@ +../mlsys.bib \ No newline at end of file diff --git a/zh_chapters/references b/zh_chapters/references deleted file mode 120000 index 543a78f..0000000 --- a/zh_chapters/references +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/references \ No newline at end of file diff --git a/zh_chapters/static b/zh_chapters/static deleted file mode 120000 index 1ca9b6a..0000000 --- a/zh_chapters/static +++ /dev/null @@ -1 +0,0 @@ -/chivier-disk/hyq-home/Projects/openmlsys-zh/static \ No newline at end of file