From 5b360b2ee554c07b236e060b796b37f450b495bd Mon Sep 17 00:00:00 2001
From: bachelor-dou <15529241576@163.com>
Date: Thu, 12 Mar 2026 08:08:40 +0000
Subject: [PATCH] update onnxruntime docs, sync CANN quick start from upstream
at build time
---
.gitignore | 1 +
Makefile | 26 ++-
_static/custom.css | 39 +++++
_static/onnxruntime_quickstart.js | 14 ++
conf.py | 1 +
index.rst | 2 +-
sources/onnxruntime/index.rst | 2 +-
sources/onnxruntime/quick_start.rst | 244 ----------------------------
8 files changed, 81 insertions(+), 248 deletions(-)
create mode 100644 _static/onnxruntime_quickstart.js
delete mode 100644 sources/onnxruntime/quick_start.rst
diff --git a/.gitignore b/.gitignore
index c2e1aefd..c4f7724b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,4 @@ sources/_generated/
.tasks/
venv/
_repos/
+_static/ascend_config.json
diff --git a/Makefile b/Makefile
index b15972f2..3495e930 100644
--- a/Makefile
+++ b/Makefile
@@ -24,11 +24,15 @@ ASCEND_CONFIG := _static/ascend_config.json
# Fetch script
FETCH_SCRIPT := scripts/fetch_ascend_data.py
+# Official ONNX Runtime CANN EP quick start source
+ONNXRUNTIME_CANN_MD_URL := https://raw.githubusercontent.com/microsoft/onnxruntime/gh-pages/docs/execution-providers/community-maintained/CANN-ExecutionProvider.md
+ONNXRUNTIME_CANN_MD_LOCAL := sources/_generated/sources/onnxruntime/quick_start.md
+
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-.PHONY: help Makefile copy-docs clean-submodules fetch-config
+.PHONY: help Makefile copy-docs clean-submodules fetch-config sync-onnxruntime-doc
# Fetch ascend config (always run to ensure freshness)
.PHONY: $(ASCEND_CONFIG)
@@ -36,6 +40,24 @@ fetch-config:
@echo "Fetching ascend configuration data..."
@python3 $(FETCH_SCRIPT)
+# Sync latest ONNX Runtime CANN EP doc from official gh-pages branch
+sync-onnxruntime-doc:
+ @echo "Syncing ONNX Runtime CANN quick start from upstream..."
+ @mkdir -p $(dir $(ONNXRUNTIME_CANN_MD_LOCAL))
+ @curl -fsSL "$(ONNXRUNTIME_CANN_MD_URL)" -o "$(ONNXRUNTIME_CANN_MD_LOCAL).tmp"
+ @awk 'BEGIN{in_fm=0} \
+ {sub(/\r$$/, "", $$0)} \
+ NR==1 && $$0=="---" {in_fm=1; next} \
+ in_fm && $$0=="---" {in_fm=0; next} \
+ in_fm {next} \
+ $$0 ~ /^##[[:space:]]+Contents[[:space:]]*$$/ {next} \
+ $$0 ~ /^\{:[[:space:]]*\.no_toc[[:space:]]*\}$$/ {next} \
+ $$0 ~ /^\{:[[:space:]]*toc[[:space:]]*\}$$/ {next} \
+ $$0 ~ /^\*[[:space:]]*TOC[[:space:]]+placeholder[[:space:]]*$$/ {next} \
+ {print}' "$(ONNXRUNTIME_CANN_MD_LOCAL).tmp" > "$(ONNXRUNTIME_CANN_MD_LOCAL)"
+ @rm -f "$(ONNXRUNTIME_CANN_MD_LOCAL).tmp"
+ @echo "Synced to $(ONNXRUNTIME_CANN_MD_LOCAL)"
+
# Initialize submodules if not exists (use pinned commits for reproducibility)
_repos/verl _repos/VeOmni _repos/LLaMA-Factory _repos/ms-swift:
@echo "Initializing submodules..."
@@ -65,7 +87,7 @@ clean-submodules:
@git submodule deinit -f _repos/*
# Explicit build targets with prerequisites
-html dirhtml singlehtml latex pdf: fetch-config copy-docs
+html dirhtml singlehtml latex pdf: fetch-config copy-docs sync-onnxruntime-doc
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
# Catch-all target for other Sphinx targets (clean, help, etc.)
diff --git a/_static/custom.css b/_static/custom.css
index 7dda4af4..b3b2e0c9 100644
--- a/_static/custom.css
+++ b/_static/custom.css
@@ -318,6 +318,45 @@
margin-bottom: 5%;
}
+body.onnxruntime-quickstart-page .rst-content {
+ color: #27384a;
+ font-size: 16px;
+ line-height: 1.75;
+}
+
+body.onnxruntime-quickstart-page .rst-content h1,
+body.onnxruntime-quickstart-page .rst-content h2,
+body.onnxruntime-quickstart-page .rst-content h3 {
+ color: #1f4b8f;
+}
+
+body.onnxruntime-quickstart-page .rst-content h1 {
+ border-bottom: 1px solid #d8e3f2;
+ padding-bottom: 8px;
+}
+
+body.onnxruntime-quickstart-page .rst-content a {
+ color: #1f63d8;
+}
+
+body.onnxruntime-quickstart-page .rst-content table.docutils {
+ border: 1px solid #d8e3f2;
+}
+
+body.onnxruntime-quickstart-page .rst-content table.docutils th {
+ background: #f2f7ff;
+}
+
+body.onnxruntime-quickstart-page .rst-content table.docutils tr:nth-child(even) td {
+ background: #f9fbff;
+}
+
+body.onnxruntime-quickstart-page .rst-content .highlight {
+ background: #f7faff;
+ border: 1px solid #d8e3f2;
+ border-radius: 6px;
+}
+
.box .flex-grow {
flex-grow: 1; /* 让文本内容占据剩余空间 */
}
diff --git a/_static/onnxruntime_quickstart.js b/_static/onnxruntime_quickstart.js
new file mode 100644
index 00000000..239e5892
--- /dev/null
+++ b/_static/onnxruntime_quickstart.js
@@ -0,0 +1,14 @@
+(function () {
+ function isQuickstartPage() {
+ var pathname = window.location.pathname.toLowerCase();
+ return pathname.indexOf('onnxruntime') !== -1 && pathname.indexOf('quick_start') !== -1;
+ }
+
+ document.addEventListener('DOMContentLoaded', function () {
+ if (!isQuickstartPage()) {
+ return;
+ }
+
+ document.body.classList.add('onnxruntime-quickstart-page');
+ });
+})();
diff --git a/conf.py b/conf.py
index aedc8f87..3b0a4410 100644
--- a/conf.py
+++ b/conf.py
@@ -73,6 +73,7 @@ def setup(app):
app.add_css_file('custom.css')
app.add_js_file('package_info.js')
app.add_js_file('statistics.js')
+ app.add_js_file('onnxruntime_quickstart.js')
# Generate ascend_config.json if it doesn't exist (for RTD/CI builds)
import os.path
diff --git a/index.rst b/index.rst
index 48247751..35887271 100644
--- a/index.rst
+++ b/index.rst
@@ -233,7 +233,7 @@
跨平台高性能推理加速器,v1.13.1 起支持昇腾。
-
+
diff --git a/sources/onnxruntime/index.rst b/sources/onnxruntime/index.rst
index b0164d9e..78e0dfed 100644
--- a/sources/onnxruntime/index.rst
+++ b/sources/onnxruntime/index.rst
@@ -5,4 +5,4 @@ onnxruntime
:maxdepth: 2
install.rst
- quick_start.rst
+ ../_generated/sources/onnxruntime/quick_start
diff --git a/sources/onnxruntime/quick_start.rst b/sources/onnxruntime/quick_start.rst
deleted file mode 100644
index 39a83caa..00000000
--- a/sources/onnxruntime/quick_start.rst
+++ /dev/null
@@ -1,244 +0,0 @@
-快速开始
-===========
-
-.. note::
- 阅读本篇前,请确保已按照 :doc:`安装指南 <./install>` 准备好昇腾环境及 ONNX Runtime!
-
-本教程以一个简单的 resnet50 模型为例,讲述如何在 Ascend NPU上使用 ONNX Runtime 进行模型推理。
-
-环境准备
------------
-
-安装本教程所依赖的额外必要库。
-
-.. code-block:: shell
- :linenos:
-
- pip install numpy Pillow onnx
-
-模型准备
------------
-
-ONNX Runtime 推理需要 ONNX 格式模型作为输入,目前有以下几种主流途径获得 ONNX 模型。
-
-1. 从 `ONNX Model Zoo `_ 中下载模型。
-2. 从 torch、TensorFlow 等框架导出 ONNX 模型。
-3. 使用转换工具,完成其他类型到 ONNX 模型的转换。
-
-本教程使用的 resnet50 模型是从 ONNX Model Zoo 中直接下载的,具体的 `下载链接 `_
-
-类别标签
------------
-
-类别标签用于将输出权重转换成人类可读的类别信息,具体的 `下载链接 `_
-
-模型推理
------------
-
-python推理示例
-~~~~~~~~~~~~~~~~~~~~
-.. code-block:: python
- :linenos:
-
- import onnxruntime as ort
- import numpy as np
- import onnx
- from PIL import Image
-
- def preprocess(image_path):
- img = Image.open(image_path)
- img = img.resize((224, 224))
- img = np.array(img).astype(np.float32)
-
- img = np.transpose(img, (2, 0, 1))
- img = img / 255.0
- mean = np.array([0.485, 0.456, 0.406]).reshape(3, 1, 1)
- std = np.array([0.229, 0.224, 0.225]).reshape(3, 1, 1)
- img = (img - mean) / std
- img = np.expand_dims(img, axis=0)
- return img
-
- def inference(model_path, img):
- options = ort.SessionOptions()
- providers = [
- (
- "CANNExecutionProvider",
- {
- "device_id": 0,
- "arena_extend_strategy": "kNextPowerOfTwo",
- "npu_mem_limit": 2 * 1024 * 1024 * 1024,
- "op_select_impl_mode": "high_performance",
- "optypelist_for_implmode": "Gelu",
- "enable_cann_graph": True
- },
- ),
- "CPUExecutionProvider",
- ]
-
- session = ort.InferenceSession(model_path, sess_options=options, providers=providers)
- input_name = session.get_inputs()[0].name
- output_name = session.get_outputs()[0].name
-
- result = session.run([output_name], {input_name: img})
- return result
-
- def display(classes_path, result):
- with open(classes_path) as f:
- labels = [line.strip() for line in f.readlines()]
-
- pred_idx = np.argmax(result)
- print(f'Predicted class: {labels[pred_idx]} ({result[0][0][pred_idx]:.4f})')
-
- if __name__ == '__main__':
- model_path = '~/model/resnet/resnet50.onnx'
- image_path = '~/model/resnet/cat.jpg'
- classes_path = '~/model/resnet/imagenet_classes.txt'
-
- img = preprocess(image_path)
- result = inference(model_path, img)
- display(classes_path, result)
-
-C++推理示例
-~~~~~~~~~~~~~~~~~
-.. code-block:: c++
- :linenos:
-
- #include
- #include
-
- #include "onnxruntime_cxx_api.h"
-
- // path of model, Change to user's own model path
- const char* model_path = "./onnx/resnet50_Opset16.onnx";
-
- /**
- * @brief Input data preparation provided by user.
- *
- * @param num_input_nodes The number of model input nodes.
- * @return A collection of input data.
- */
- std::vector> input_prepare(size_t num_input_nodes) {
- std::vector> input_datas;
- input_datas.reserve(num_input_nodes);
-
- constexpr size_t input_data_size = 3 * 224 * 224;
- std::vector input_data(input_data_size);
- // initialize input data with values in [0.0, 1.0]
- for (unsigned int i = 0; i < input_data_size; i++)
- input_data[i] = (float)i / (input_data_size + 1);
- input_datas.push_back(input_data);
-
- return input_datas;
- }
-
- /**
- * @brief Model output data processing logic(For User updates).
- *
- * @param output_tensors The results of the model output.
- */
- void output_postprocess(std::vector& output_tensors) {
- auto floatarr = output_tensors.front().GetTensorMutableData();
-
- for (int i = 0; i < 5; i++) {
- std::cout << "Score for class [" << i << "] = " << floatarr[i] << '\n';
- }
-
- std::cout << "Done!" << std::endl;
- }
-
- /**
- * @brief The main functions for model inference.
- *
- * The complete model inference process, which generally does not need to be
- * changed here
- */
- void inference() {
- const auto& api = Ort::GetApi();
- Ort::Env env(ORT_LOGGING_LEVEL_WARNING);
-
- // Enable cann graph in cann provider option.
- OrtCANNProviderOptions* cann_options = nullptr;
- api.CreateCANNProviderOptions(&cann_options);
-
- // Configurations of EP
- std::vector keys{
- "device_id",
- "npu_mem_limit",
- "arena_extend_strategy",
- "enable_cann_graph"};
- std::vector values{"0", "4294967296", "kNextPowerOfTwo", "1"};
- api.UpdateCANNProviderOptions(
- cann_options, keys.data(), values.data(), keys.size());
-
- // Convert to general session options
- Ort::SessionOptions session_options;
- api.SessionOptionsAppendExecutionProvider_CANN(
- static_cast(session_options), cann_options);
-
- Ort::Session session(env, model_path, session_options);
-
- Ort::AllocatorWithDefaultOptions allocator;
-
- // Input Process
- const size_t num_input_nodes = session.GetInputCount();
- std::vector input_node_names;
- std::vector input_names_ptr;
- input_node_names.reserve(num_input_nodes);
- input_names_ptr.reserve(num_input_nodes);
- std::vector> input_node_shapes;
- std::cout << num_input_nodes << std::endl;
- for (size_t i = 0; i < num_input_nodes; i++) {
- auto input_name = session.GetInputNameAllocated(i, allocator);
- input_node_names.push_back(input_name.get());
- input_names_ptr.push_back(std::move(input_name));
- auto type_info = session.GetInputTypeInfo(i);
- auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
- input_node_shapes.push_back(tensor_info.GetShape());
- }
-
- // Output Process
- const size_t num_output_nodes = session.GetOutputCount();
- std::vector output_node_names;
- std::vector output_names_ptr;
- output_names_ptr.reserve(num_input_nodes);
- output_node_names.reserve(num_output_nodes);
- for (size_t i = 0; i < num_output_nodes; i++) {
- auto output_name = session.GetOutputNameAllocated(i, allocator);
- output_node_names.push_back(output_name.get());
- output_names_ptr.push_back(std::move(output_name));
- }
-
- // User need to generate input date according to real situation.
- std::vector> input_datas = input_prepare(num_input_nodes);
-
- auto memory_info = Ort::MemoryInfo::CreateCpu(
- OrtAllocatorType::OrtArenaAllocator, OrtMemTypeDefault);
-
- std::vector input_tensors;
- input_tensors.reserve(num_input_nodes);
- for (size_t i = 0; i < input_node_shapes.size(); i++) {
- auto input_tensor = Ort::Value::CreateTensor(
- memory_info,
- input_datas[i].data(),
- input_datas[i].size(),
- input_node_shapes[i].data(),
- input_node_shapes[i].size());
- input_tensors.push_back(std::move(input_tensor));
- }
-
- auto output_tensors = session.Run(
- Ort::RunOptions{nullptr},
- input_node_names.data(),
- input_tensors.data(),
- num_input_nodes,
- output_node_names.data(),
- output_node_names.size());
-
- // Processing of out_tensor
- output_postprocess(output_tensors);
- }
-
- int main(int argc, char* argv[]) {
- inference();
- return 0;
- }
\ No newline at end of file