diff --git a/.gitignore b/.gitignore
index b559aa3a..c2e1aefd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,4 +3,8 @@ _build/*
.vscode
.DS_Store
sources/pytorch/api_doc.rst
-sources/_generated
\ No newline at end of file
+sources/_generated_static/ascend_config.json
+sources/_generated/
+.tasks/
+venv/
+_repos/
diff --git a/Makefile b/Makefile
index c04f3ba5..b15972f2 100644
--- a/Makefile
+++ b/Makefile
@@ -18,18 +18,31 @@ PROJECT_CONFIGS = \
# Configure all subprojects generated path
GENERATED_DOCS := sources/_generated
+# Ascend config file path
+ASCEND_CONFIG := _static/ascend_config.json
+
+# Fetch script
+FETCH_SCRIPT := scripts/fetch_ascend_data.py
+
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-.PHONY: help Makefile
+.PHONY: help Makefile copy-docs clean-submodules fetch-config
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
+# Fetch ascend config (always run to ensure freshness)
+.PHONY: $(ASCEND_CONFIG)
+fetch-config:
+ @echo "Fetching ascend configuration data..."
+ @python3 $(FETCH_SCRIPT)
+
+# Initialize submodules if not exists (use pinned commits for reproducibility)
+_repos/verl _repos/VeOmni _repos/LLaMA-Factory _repos/ms-swift:
@echo "Initializing submodules..."
- @git submodule update --init --remote
+ @git submodule update --init
+# Copy documentation from submodules
+copy-docs: _repos/verl _repos/VeOmni _repos/LLaMA-Factory _repos/ms-swift
@echo "Preparing generated docs directory..."
@mkdir -p $(GENERATED_DOCS)
@@ -39,20 +52,22 @@ help:
rel_dst=$$(echo $$config | cut -d: -f2); \
dst="$(GENERATED_DOCS)/$$rel_dst"; \
echo "Copying $$src -> $$dst"; \
- \
- # Clean destination to avoid stale files \
rm -rf $$dst; \
mkdir -p $$dst; \
- \
- # Remove index files from source to avoid conflicts \
find $$src -name 'index.*' -delete 2>/dev/null || true; \
- \
echo "Copying $$src to $$dst"; \
- cp -r "$$src"/* "$$dst"/ 2>/dev/null || \
- echo " [WARN] Source directory does not exist or is empty: $$src"; \
+ cp -r "$$src"/* "$$dst"/ 2>/dev/null || echo " [WARN] Source directory does not exist or is empty: $$src"; \
done
+# Clean up submodules
+clean-submodules:
@echo "Cleaning up submodules..."
@git submodule deinit -f _repos/*
+# Explicit build targets with prerequisites
+html dirhtml singlehtml latex pdf: fetch-config copy-docs
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+# Catch-all target for other Sphinx targets (clean, help, etc.)
+%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
\ No newline at end of file
diff --git a/_static/ascend_actions.js b/_static/ascend_actions.js
index 7327ed5c..98641055 100644
--- a/_static/ascend_actions.js
+++ b/_static/ascend_actions.js
@@ -1,253 +1,229 @@
$(document).ready(function () {
- $.reset_selection = function (elem) {
- elem.parent().children().each(function () {
- $(this).removeClass("selected");
+ var config = null;
+ var selectedOptions = {
+ version: null,
+ product: null,
+ cpu_arch: null,
+ os: null,
+ install_method: null
+ };
+
+ function loadConfig() {
+ $.getJSON('../../_static/ascend_config.json', function(data) {
+ config = data;
+ initializeUI();
+ }).fail(function() {
+ console.error('Failed to load ascend_config.json');
+ $('#install-instructions').html('
加载配置文件失败,请检查网络连接。
');
+ $('#install-instructions').show();
});
}
- $.get_options = function () {
- var options = {};
- $('#col-values').children().each(function () {
- var elem = $(this).find(".selected").each(function () {
- var id = $(this).attr("id").split("-");
- var category = id[0];
- var value = id[1];
- if (value === "version") {
- if (category === "cann")
- value = $(this).val();
- else
- value = $(this).data('version');
- }
- options[category] = value;
- });
- });
- return options;
- }
+ function initializeUI() {
+ if (!config) return;
- $.get_docker_os_versions = function (options) {
- var os_versions = {};
- $.each(docker_images, function (idx, image) {
- var tag = image.split(":")[1];
- var tag_items = tag.split("-");
- var npu_type = tag_items[1];
-
- var os = tag_items[2];
- var index = os.search(/\d/);
- var os_type = os.substring(0, index);
- var os_version = os.substring(index);
-
- if (options['os'] === os_type && options['npu'] === npu_type) {
- if (!os_versions[os_type]) {
- os_versions[os_type] = new Set();
- }
- os_versions[os_type].add(os_version);
- }
+ var versions = config.versions;
+ var versionKeys = Object.keys(versions);
+
+ var versionHtml = '版本
';
+ versionKeys.forEach(function(key, index) {
+ var version = versions[key];
+ var selected = index === 0 ? 'selected' : '';
+ var blockClass = 'block-' + Math.min(versionKeys.length, 5);
+ versionHtml += '' + escapeHtml(version.name) + '
';
});
- return os_versions;
- }
+ $('#row-version').html(versionHtml);
- $.update_os_verions = function () {
- $("#row-os_version").find("div").not(":first").remove();
- var options = $.get_options();
- // update os_versions
- var os_versions = $.get_docker_os_versions(options);
- var selected_os_versions = os_versions[options['os']];
- if (selected_os_versions == null) {
- $('#row-os_version').append('无可用版本
');
- } else {
- var version_length = selected_os_versions.size;
- selected_os_versions.forEach(function (version) {
- $('#row-os_version').append('' + version + '
');
- });
- $("#row-os_version div:last-child").addClass("selected");
+ if (versionKeys.length > 0) {
+ selectedOptions.version = versionKeys[0];
+ updateProductSeries();
}
}
- $.change_options_visible = function () {
- var options = $.get_options();
- if (options['install_type'] === 'direct') {
- $("#header-os_version").hide();
- $("#row-os_version").hide();
- } else {
- $("#header-os_version").show();
- $("#row-os_version").show();
- }
- }
+ function updateProductSeries() {
+ if (!config || !selectedOptions.version) return;
- $.update_cann_versions = function () {
- // reset table.
- var cann_version_select = $('#cann-version');
- cann_version_select.empty();
- $.reset_selection(cann_version_select);
- $('#driver-version').text("Driver");
- $('#firmware-version').text("Firmware");
-
- var options = $.get_options();
- // not using docker.
- if (options['install_type'] === "direct") {
- // update select list.
- $.each(package_info, function (key, value) {
- if (options['npu'] in value) {
- cann_version_select.append(new Option("CANN: " + key, key));
- }
- });
- } else {
- $.each(package_info, function (key, value) {
- // not all version has a docker image.
- const option_tag = key.toLowerCase() + "-" + options['npu'] + "-" + options['os'] + options['os_version'];
- const pkg_info = package_info[key][options['npu']];
- for (const image of docker_images) {
- const image_tag = image.split(":")[1];
- if (image_tag.includes(option_tag) && pkg_info &&
- pkg_info.driver_version && pkg_info.firmware_version) {
- cann_version_select.append(new Option("CANN: " + key, key));
- break;
- }
- }
- });
- }
- if (cann_version_select.children().length < 1) {
- cann_version_select.children().first().text('无可用版本');
+ var version = config.versions[selectedOptions.version];
+ var productSeries = version.product_series;
+ var productKeys = Object.keys(productSeries);
+
+ var productHtml = '产品系列
';
+ productKeys.forEach(function(key, index) {
+ var product = productSeries[key];
+ var selected = index === 0 ? 'selected' : '';
+ var blockClass = 'block-' + Math.min(productKeys.length, 5);
+ productHtml += '' + escapeHtml(product.name) + '
';
+ });
+ $('#row-product').html(productHtml);
+
+ if (productKeys.length > 0) {
+ selectedOptions.product = productKeys[0];
+ updateCPUArchitectures();
}
- cann_version_select.trigger('change');
}
- $("#col-values").on("click", ".values-element", function () {
- id = $(this).attr("id");
- fields = id.split("-");
- if (fields[1] == "version")
- return;
-
- $.reset_selection($(this));
- $(this).addClass("selected");
+ function updateCPUArchitectures() {
+ if (!config || !selectedOptions.version || !selectedOptions.product) return;
+
+ var version = config.versions[selectedOptions.version];
+ var productSeries = version.product_series;
+ var product = productSeries[selectedOptions.product];
+ var cpuArchs = product.cpu_architectures;
+ var cpuArchKeys = Object.keys(cpuArchs);
+
+ var cpuArchHtml = 'CPU架构
';
+ cpuArchKeys.forEach(function(key, index) {
+ var cpuArch = cpuArchs[key];
+ var selected = index === 0 ? 'selected' : '';
+ var blockClass = 'block-' + Math.min(cpuArchKeys.length, 5);
+ cpuArchHtml += '' + escapeHtml(cpuArch.name) + '
';
+ });
+ $('#row-cpu_arch').html(cpuArchHtml);
- // if os changed, update os version.
- if (fields[0] === "os" || fields[0] === "npu") {
- $.update_os_verions();
+ if (cpuArchKeys.length > 0) {
+ selectedOptions.cpu_arch = cpuArchKeys[0];
+ updateOperatingSystems();
}
+ }
+
+ function updateOperatingSystems() {
+ if (!config || !selectedOptions.version || !selectedOptions.product || !selectedOptions.cpu_arch) return;
+
+ var version = config.versions[selectedOptions.version];
+ var productSeries = version.product_series;
+ var product = productSeries[selectedOptions.product];
+ var cpuArch = product.cpu_architectures[selectedOptions.cpu_arch];
+ var operatingSystems = cpuArch.operating_systems;
+ var osKeys = Object.keys(operatingSystems);
+
+ var osHtml = '操作系统
';
+ osKeys.forEach(function(key, index) {
+ var os = operatingSystems[key];
+ var selected = index === 0 ? 'selected' : '';
+ var blockClass = 'block-' + Math.min(osKeys.length, 5);
+ osHtml += '' + escapeHtml(os.name) + '
';
+ });
+ $('#row-os').html(osHtml);
- // if install type changed, update options visible.
- if (fields[0] === "install_type") {
- $.change_options_visible();
+ if (osKeys.length > 0) {
+ selectedOptions.os = osKeys[0];
+ updateInstallMethods();
}
+ }
- // update_cann_version if any option changed.
- $.update_cann_versions();
- });
+ function updateInstallMethods() {
+ if (!config || !selectedOptions.version || !selectedOptions.product || !selectedOptions.cpu_arch || !selectedOptions.os) return;
+
+ var version = config.versions[selectedOptions.version];
+ var productSeries = version.product_series;
+ var product = productSeries[selectedOptions.product];
+ var cpuArch = product.cpu_architectures[selectedOptions.cpu_arch];
+ var operatingSystems = cpuArch.operating_systems[selectedOptions.os];
+ var installMethods = operatingSystems.install_methods;
+ var installMethodKeys = Object.keys(installMethods);
+
+ var installMethodHtml = '安装方式
';
+ installMethodKeys.forEach(function(key, index) {
+ var installMethod = installMethods[key];
+ var selected = index === 0 ? 'selected' : '';
+ var blockClass = 'block-' + Math.min(installMethodKeys.length, 5);
+ installMethodHtml += '' + escapeHtml(installMethod.name) + '
';
+ });
+ $('#row-install_method').html(installMethodHtml);
- $("#col-values").on("change", "select", function () {
- // select cann, driver, formware versions.
- $.reset_selection($(this));
- $('#driver-version').text("Driver");
- $('#firmware-version').text("Firmware");
-
- if ($(this).val() !== "na") {
- $(this).addClass("selected");
- $('#driver-version').addClass("selected");
- $('#firmware-version').addClass("selected");
-
- var options = $.get_options();
- var driver_version = package_info[options['cann']][options['npu']].driver_version;
- var firmware_version = package_info[options['cann']][options['npu']].firmware_version;
- $('#driver-version').text("Driver: " + driver_version);
- $('#driver-version').data("version", driver_version);
- $('#firmware-version').text("Firmware: " + firmware_version);
- $('#firmware-version').data("version", firmware_version);
+ if (installMethodKeys.length > 0) {
+ selectedOptions.install_method = installMethodKeys[0];
+ updateInstructions();
}
- $.gen_content();
- });
+ }
- $.gen_content = function () {
- // instructions need all options selected.
- if ($('#cann-version').val() !== "na") {
- $('#install-instructions').show();
- } else {
- $('#install-instructions').hide();
- return
- }
+ function updateInstructions() {
+ if (!config || !selectedOptions.version || !selectedOptions.product || !selectedOptions.cpu_arch || !selectedOptions.os || !selectedOptions.install_method) return;
- var options = $.get_options();
+ var version = config.versions[selectedOptions.version];
+ var productSeries = version.product_series;
+ var product = productSeries[selectedOptions.product];
+ var cpuArch = product.cpu_architectures[selectedOptions.cpu_arch];
+ var operatingSystems = cpuArch.operating_systems[selectedOptions.os];
+ var installMethod = operatingSystems.install_methods[selectedOptions.install_method];
+ var steps = installMethod.steps;
- // install os dependency.
- if (options['os'] === 'ubuntu') {
- $('#install-dependencies-ubuntu').show();
- $('#install-dependencies-openeuler').hide();
- } else {
- $('#install-dependencies-ubuntu').hide();
- $('#install-dependencies-openeuler').show();
+ if (!steps || steps.length === 0) {
+ $('#install-instructions').html('暂无安装步骤
');
+ $('#install-instructions').show();
+ return;
}
- var driver_url = package_info[options['cann']][options['npu']][options['arch']].driver_url;
- var firmware_url = package_info[options['cann']][options['npu']].firmware_url;
- var cann_url = package_info[options['cann']][options['arch']].url;
- var kernel_url = package_info[options['cann']][options['npu']].kernel_url;
+ var instructionsHtml = '';
+ steps.forEach(function(step, index) {
+ instructionsHtml += '';
+ instructionsHtml += '' + (index + 1) + '. ' + escapeHtml(step.title) + '
';
+
+ if (step.commands && step.commands.length > 0) {
+ step.commands.forEach(function(command) {
+ instructionsHtml += '';
+ instructionsHtml += '
';
+ instructionsHtml += '
' + escapeHtml(command) + '
';
+ instructionsHtml += '
';
+ instructionsHtml += '
';
+ });
+ }
- if (kernel_url == undefined) {
- kernel_url = package_info[options['cann']][options['npu']][options['arch']].kernel_url;
- }
+ instructionsHtml += '';
+ });
- var parts = driver_url.split("/");
- var driver_name = parts[parts.length - 1];
- parts = firmware_url.split("/");
- var firmware_name = parts[parts.length - 1];
- parts = cann_url.split("/");
- var cann_name = parts[parts.length - 1];
+ // 添加底部提示信息
+ instructionsHtml += '';
+
+ $('#install-instructions').html(instructionsHtml);
+ $('#install-instructions').show();
+ }
- // download and install driver
- $('#codecell6').html('wget "' + driver_url + '"\nsudo sh ' + driver_name + ' --full --install-for-all');
+ function escapeHtml(text) {
+ return text
+ .replace(/&/g, "&")
+ .replace(//g, ">")
+ .replace(/"/g, """)
+ .replace(/'/g, "'");
+ }
- // download and install firmware
- $('#codecell8').html('wget "' + firmware_url + '"\nsudo sh ' + firmware_name + ' --full');
+ function resetSelection(elem) {
+ elem.parent().children().each(function () {
+ $(this).removeClass("selected");
+ });
+ }
- if (options['install_type'] === 'direct') {
- // download and install cann
- $('#codecell11').html('wget "' + cann_url + '"\nsh ' + cann_name + ' --full');
+ $("#col-values").on("click", ".values-element", function () {
+ var id = $(this).attr("id");
+ var fields = id.split("-");
- // download and install kernel if exist.
- if (kernel_url == null) {
- $('#install_kernel_section').hide();
- }
- else {
- parts = kernel_url.split("/");
- var kernel_name = parts[parts.length - 1];
- $('#install_kernel_section').show();
- // download and install kernel
- $('#codecell14').html('wget "' + kernel_url + '"\nsh ' + kernel_name + ' --install');
- }
+ resetSelection($(this));
+ $(this).addClass("selected");
- $('#use_docker_section').hide();
- $('#install_cann_section').show();
- } else {
- const option_tag = options['cann'].toLowerCase() + "-" + options['npu'] + "-" + options['os'] + options['os_version'];
- for (let i = 0; i < docker_images.length; i++) {
- const image_tag = docker_images[i].split(":")[1];
- if (image_tag.includes(option_tag)) {
- const dockerCommand = `
-docker run \\
- --name cann_container \\
- --device /dev/davinci1 \\
- --device /dev/davinci_manager \\
- --device /dev/devmm_svm \\
- --device /dev/hisi_hdc \\
- -v /usr/local/dcmi:/usr/local/dcmi \\
- -v /usr/local/bin/npu-smi:/usr/local/bin/npu-smi \\
- -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ \\
- -v /usr/local/Ascend/driver/version.info:/usr/local/Ascend/driver/version.info \\
- -v /etc/ascend_install.info:/etc/ascend_install.info \\
- -it ${docker_images[i]} bash
- `;
-
- $('#codecell16').html(dockerCommand.trim());
- break;
- }
- }
- $('#install_cann_section').hide();
- $('#use_docker_section').show();
+ if (fields[0] === "version") {
+ selectedOptions.version = fields[1];
+ updateProductSeries();
+ } else if (fields[0] === "product") {
+ selectedOptions.product = fields[1];
+ updateCPUArchitectures();
+ } else if (fields[0] === "cpu_arch") {
+ selectedOptions.cpu_arch = fields[1];
+ updateOperatingSystems();
+ } else if (fields[0] === "os") {
+ selectedOptions.os = fields[1];
+ updateInstallMethods();
+ } else if (fields[0] === "install_method") {
+ selectedOptions.install_method = fields[1];
+ updateInstructions();
}
- }
+ });
- $.update_os_verions();
- $.change_options_visible();
- $.update_cann_versions();
-
+ loadConfig();
});
diff --git a/_static/custom.css b/_static/custom.css
index e702f843..7dda4af4 100644
--- a/_static/custom.css
+++ b/_static/custom.css
@@ -2,25 +2,25 @@
.wy-nav-content {
max-width: 1200px;
}
-
+
/* code block highlight color in rtd changed to lime green, no no no */
-
+
.rst-content tt.literal, .rst-content code.literal, .highlight {
background: #f0f0f0;
}
.rst-content tt.literal, .rst-content code.literal {
color: #000000;
}
-
+
/* Footer privacy links */
a#wap_dns {
display: none;
}
-
+
a#wap_nac {
display: none;
}
-
+
/* replace the copyright to eliminate the copyright symbol enforced by
the ReadTheDocs theme */
div[role=contentinfo] {
@@ -34,7 +34,7 @@
div.version p {
color: #FFFF00;
}
-
+
.menu {
display: flex;
flex-wrap: wrap;
@@ -42,7 +42,7 @@
margin: auto;
padding: 10px 24px 24px 24px;
}
-
+
.menu-element {
flex: 1 1 48%;
background-color: #F3F4F7;
@@ -52,25 +52,25 @@
padding: 10px 24px;
cursor: pointer;
}
-
+
@media screen and (max-width: 768px) {
.menu-element {
width: 100%;
}
}
-
+
.menu-element:hover {
background-color: #c41c24;
color: white;
}
-
+
.menu-element.selected {
background-color: #c41c24;
color: white;
}
-
-
-
+
+
+
.row {
display: flex;
flex-wrap: wrap;
@@ -78,20 +78,20 @@
margin: auto;
padding: 0px 2px;
}
-
+
.row-element-1 {
flex: 1 1 20%;
display: block;
margin-top: auto;
margin-bottom: auto;
}
-
+
.row-element-2 {
flex: 1 1 80%;
margin-top: auto;
margin-bottom: auto;
}
-
+
.mobile-headings {
flex: 1 1 auto;
color: black;
@@ -100,13 +100,13 @@
padding: 10px 24px;
display: none;
}
-
+
.headings-element {
text-align: left;
margin: 2px;
padding: 10px 24px;
}
-
+
.values-element {
background-color: #F3F4F7;
color: black;
@@ -124,60 +124,80 @@
padding: 10px 24px;
cursor: pointer;
}
-
+
.block-1 {
flex: 1 1 100%;
}
-
+
.block-2 {
flex: 1 1 49%;
}
-
+
.block-3 {
flex: 1 1 32%;
}
-
+
.block-4 {
flex: 1 1 24%;
}
-
+
.block-5 {
flex: 1 1 19%;
}
-
+
+ .more-version {
+ flex: 1 1 auto;
+ min-width: 80px;
+ }
+
+ .more-versions-btn {
+ display: inline-block;
+ padding: 8px 16px;
+ background-color: #f3f4f7;
+ color: #333;
+ text-decoration: none;
+ border-radius: 4px;
+ font-size: 14px;
+ }
+
+ .more-versions-btn:hover {
+ background-color: #c41c24;
+ color: white;
+ }
+
@media screen and (max-width: 1050px) {
.row-element-1 {
display: none;
}
-
+
.row-element-2 {
flex: 1 1 100%;
}
-
+
.mobile-headings {
display: block;
}
-
+
.block-2,.block-3,.block-4,.block-5 {
flex: 1 1 100%;
}
}
-
+
.values-element:hover {
background-color: #c41c24;
color: white;
}
-
+
.values-element.selected {
background-color: #c41c24;
color: white;
}
-
+
#install-instructions {
padding-top: 50px;
}
- .container {
+.container {
max-width: 100%;
margin-left: auto;
margin-right: auto;
@@ -303,4 +323,4 @@
}
-/* card-icon 样式已移至 index.rst 中统一管理 */
+/* card-icon 样式已移至 index.rst 中统一管理 */
\ No newline at end of file
diff --git a/conf.py b/conf.py
index 28026c44..aedc8f87 100644
--- a/conf.py
+++ b/conf.py
@@ -74,6 +74,21 @@ def setup(app):
app.add_js_file('package_info.js')
app.add_js_file('statistics.js')
+ # Generate ascend_config.json if it doesn't exist (for RTD/CI builds)
+ import os.path
+ ascend_config_path = os.path.join(os.path.dirname(__file__), '_static', 'ascend_config.json')
+ if not os.path.exists(ascend_config_path):
+ print("ascend_config.json not found, generating...")
+ fetch_script = os.path.join(os.path.dirname(__file__), 'scripts', 'fetch_ascend_data.py')
+ if os.path.exists(fetch_script):
+ import subprocess
+ try:
+ subprocess.run(['python3', fetch_script], check=True)
+ except Exception as e:
+ print(f"Warning: Failed to generate ascend_config.json: {e}")
+ else:
+ print(f"Warning: fetch script not found at {fetch_script}")
+
import os, re, importlib.util
from jinja2 import Environment, FileSystemLoader
@@ -165,4 +180,7 @@ def generate_api_doc():
f.write(rendered_content)
# 在 Sphinx 构建之前调用该函数生成 API 文档
-generate_api_doc()
+try:
+ generate_api_doc()
+except ImportError as e:
+ print(f"Warning: {e}. Skipping API documentation generation.")
diff --git a/requirements.txt b/requirements.txt
index 1812a1cf..9c9aba78 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -8,4 +8,4 @@ sphinx_markdown_tables
sphinx-design
torch==2.5.1+cpu; platform_machine == "x86_64"
torch==2.5.1; platform_machine == "aarch64"
-torch_npu==2.5.1rc1
+torch_npu==2.5.1rc1; sys_platform == "linux"
diff --git a/scripts/fetch_ascend_data.py b/scripts/fetch_ascend_data.py
new file mode 100644
index 00000000..0fd52a12
--- /dev/null
+++ b/scripts/fetch_ascend_data.py
@@ -0,0 +1,341 @@
+#!/usr/bin/env python3
+import json
+import os
+import re
+import subprocess
+import sys
+import threading
+import queue
+from datetime import datetime
+from html.parser import HTMLParser
+
+# 进度追踪
+progress_lock = threading.Lock()
+progress_count = 0
+
+def update_progress():
+ """更新并显示进度"""
+ global progress_count
+ with progress_lock:
+ progress_count += 1
+ print(f"\rFetched: {progress_count}", end='', flush=True)
+
+class HTMLStepParser(HTMLParser):
+ """解析HTML内容,提取步骤和命令"""
+ def __init__(self):
+ super().__init__()
+ self.steps = []
+ self.current_step = None
+ self.in_code = False
+ self.code_content = []
+ self.in_pre = False
+ self.in_h1 = False
+ self.h1_content = []
+
+ def handle_starttag(self, tag, attrs):
+ if tag == 'h1':
+ self.in_h1 = True
+ self.h1_content = []
+ elif tag == 'pre':
+ self.in_pre = True
+ elif tag == 'code' and self.in_pre:
+ self.in_code = True
+ self.code_content = []
+
+ def handle_endtag(self, tag):
+ if tag == 'h1':
+ self.in_h1 = False
+ if self.h1_content:
+ step_title = ''.join(self.h1_content).strip()
+ if step_title:
+ self.current_step = {
+ 'title': step_title,
+ 'commands': []
+ }
+ self.steps.append(self.current_step)
+ elif tag == 'pre':
+ self.in_pre = False
+ elif tag == 'code' and self.in_pre:
+ self.in_code = False
+ if self.code_content and self.current_step:
+ code = ''.join(self.code_content).strip()
+ if code:
+ self.current_step['commands'].append(code)
+
+ def handle_data(self, data):
+ if self.in_h1:
+ self.h1_content.append(data)
+ elif self.in_code:
+ self.code_content.append(data)
+
+def parse_html_steps(html_content):
+ """解析HTML内容,提取步骤和命令"""
+ parser = HTMLStepParser()
+ parser.feed(html_content)
+ return parser.steps
+
+def api_call(url):
+ """调用hiascend API"""
+ cmd = [
+ 'curl', '-s',
+ '--max-time', '30',
+ '--connect-timeout', '10',
+ '-H', 'referer: https://www.hiascend.com/cann/download',
+ '-H', 'accept: */*',
+ '-H', 'accept-language: zh-CN,zh;q=0.9',
+ '-H', 'user-agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Mobile Safari/537.36',
+ url
+ ]
+ result = subprocess.run(cmd, capture_output=True, text=True)
+ if result.returncode == 0:
+ try:
+ return json.loads(result.stdout)
+ except json.JSONDecodeError:
+ print(f"\nWarning: Invalid JSON response from {url}")
+ return None
+ return None
+
+def get_product_series(version_id):
+ """获取产品系列列表"""
+ url = f"https://www.hiascend.com/ascendgateway/ascendservice/cannDownload/detail?lang=zh&versionId={version_id}&type=h04"
+ response = api_call(url)
+ if response and response.get('success'):
+ return response.get('data', {}).get('subOutVOList', [])
+ return []
+
+def get_cpu_architectures(version_id, hardware_id):
+ """获取CPU架构列表"""
+ url = f"https://www.hiascend.com/ascendgateway/ascendservice/cannDownload/detail?lang=zh&versionId={version_id}&hardwareId={hardware_id}&type=h05"
+ response = api_call(url)
+ if response and response.get('success'):
+ return response.get('data', {}).get('subOutVOList', [])
+ return []
+
+def get_operating_systems(version_id, hardware_id, cpu_arch_id):
+ """获取操作系统列表"""
+ url = f"https://www.hiascend.com/ascendgateway/ascendservice/cannDownload/detail?lang=zh&versionId={version_id}&hardwareId={hardware_id}&cpuArchitectureId={cpu_arch_id}&type=h06"
+ response = api_call(url)
+ if response and response.get('success'):
+ return response.get('data', {}).get('subOutVOList', [])
+ return []
+
+def get_install_methods(version_id, hardware_id, cpu_arch_id, os_id):
+ """获取安装方式列表"""
+ url = f"https://www.hiascend.com/ascendgateway/ascendservice/cannDownload/detail?lang=zh&versionId={version_id}&hardwareId={hardware_id}&cpuArchitectureId={cpu_arch_id}&operateSystemId={os_id}&type=h07"
+ response = api_call(url)
+ if response and response.get('success'):
+ return response.get('data', {}).get('subOutVOList', [])
+ return []
+
+def get_installation_steps(version_id, hardware_id, cpu_arch_id, os_id, install_method_id):
+ """获取安装步骤"""
+ url = f"https://www.hiascend.com/ascendgateway/ascendservice/cannDownload/detail?lang=zh&versionId={version_id}&hardwareId={hardware_id}&cpuArchitectureId={cpu_arch_id}&operateSystemId={os_id}&installMethodId={install_method_id}&type=h08"
+ response = api_call(url)
+ if response and response.get('success'):
+ sub_out_list = response.get('data', {}).get('subOutVOList', [])
+ if sub_out_list and len(sub_out_list) > 0:
+ html_content = sub_out_list[0].get('name', '')
+ return parse_html_steps(html_content)
+ return []
+
+def worker(task_queue, config, config_lock):
+ """工作线程,从队列获取任务并处理"""
+ while True:
+ try:
+ task = task_queue.get(timeout=1)
+ except queue.Empty:
+ break
+
+ try:
+ task_type = task['type']
+
+ if task_type == 'product_series':
+ version_id = task['version_id']
+ product_series = get_product_series(version_id)
+
+ with config_lock:
+ for product in product_series:
+ hardware_id = product['id']
+ product_name = product['name']
+ version_config = config['versions'][version_id]
+ version_config['product_series'][hardware_id] = {
+ 'id': hardware_id,
+ 'name': product_name,
+ 'cpu_architectures': {}
+ }
+ task_queue.put({
+ 'type': 'cpu_architectures',
+ 'version_id': version_id,
+ 'hardware_id': hardware_id
+ })
+
+ elif task_type == 'cpu_architectures':
+ version_id = task['version_id']
+ hardware_id = task['hardware_id']
+ cpu_archs = get_cpu_architectures(version_id, hardware_id)
+
+ with config_lock:
+ for cpu_arch in cpu_archs:
+ cpu_arch_id = cpu_arch['id']
+ cpu_arch_name = cpu_arch['name']
+ version_config = config['versions'][version_id]
+ product_config = version_config['product_series'][hardware_id]
+ product_config['cpu_architectures'][cpu_arch_id] = {
+ 'id': cpu_arch_id,
+ 'name': cpu_arch_name,
+ 'operating_systems': {}
+ }
+ task_queue.put({
+ 'type': 'operating_systems',
+ 'version_id': version_id,
+ 'hardware_id': hardware_id,
+ 'cpu_arch_id': cpu_arch_id
+ })
+
+ elif task_type == 'operating_systems':
+ version_id = task['version_id']
+ hardware_id = task['hardware_id']
+ cpu_arch_id = task['cpu_arch_id']
+ os_list = get_operating_systems(version_id, hardware_id, cpu_arch_id)
+
+ with config_lock:
+ for os_info in os_list:
+ os_id = os_info['id']
+ os_name = os_info['name']
+ version_config = config['versions'][version_id]
+ product_config = version_config['product_series'][hardware_id]
+ cpu_config = product_config['cpu_architectures'][cpu_arch_id]
+ cpu_config['operating_systems'][os_id] = {
+ 'id': os_id,
+ 'name': os_name,
+ 'install_methods': {}
+ }
+ task_queue.put({
+ 'type': 'install_methods',
+ 'version_id': version_id,
+ 'hardware_id': hardware_id,
+ 'cpu_arch_id': cpu_arch_id,
+ 'os_id': os_id
+ })
+
+ elif task_type == 'install_methods':
+ version_id = task['version_id']
+ hardware_id = task['hardware_id']
+ cpu_arch_id = task['cpu_arch_id']
+ os_id = task['os_id']
+ install_methods = get_install_methods(version_id, hardware_id, cpu_arch_id, os_id)
+
+ with config_lock:
+ for install_method in install_methods:
+ install_method_id = install_method['id']
+ install_method_name = install_method['name']
+ task_queue.put({
+ 'type': 'installation_steps',
+ 'version_id': version_id,
+ 'hardware_id': hardware_id,
+ 'cpu_arch_id': cpu_arch_id,
+ 'os_id': os_id,
+ 'install_method_id': install_method_id,
+ 'install_method_name': install_method_name
+ })
+
+ elif task_type == 'installation_steps':
+ version_id = task['version_id']
+ hardware_id = task['hardware_id']
+ cpu_arch_id = task['cpu_arch_id']
+ os_id = task['os_id']
+ install_method_id = task['install_method_id']
+ install_method_name = task['install_method_name']
+
+ steps = get_installation_steps(version_id, hardware_id, cpu_arch_id, os_id, install_method_id)
+
+ if steps:
+ with config_lock:
+ version_config = config['versions'][version_id]
+ product_config = version_config['product_series'][hardware_id]
+ cpu_config = product_config['cpu_architectures'][cpu_arch_id]
+ os_config = cpu_config['operating_systems'][os_id]
+ os_config['install_methods'][install_method_id] = {
+ 'id': install_method_id,
+ 'name': install_method_name,
+ 'steps': steps
+ }
+
+ update_progress()
+ except Exception as e:
+ print(f"\nError processing task: {e}")
+ finally:
+ task_queue.task_done()
+
+def get_git_short_hash():
+ """获取短的 git hash"""
+ try:
+ result = subprocess.run(['git', 'rev-parse', '--short', 'HEAD'],
+ capture_output=True, text=True, cwd=os.path.dirname(__file__))
+ if result.returncode == 0:
+ return result.stdout.strip()
+ except:
+ pass
+ return 'unknown'
+
+def main():
+ # 版本列表(手动记录)
+ versions = [
+ {'id': '673', 'name': '9.0.0-beta.1'},
+ {'id': '657', 'name': '8.5.0'},
+ {'id': '630', 'name': '8.5.0.alpha002'}
+ ]
+
+ config = {
+ 'version': get_git_short_hash(),
+ 'updated_at': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
+ 'versions': {}
+ }
+
+ # 初始化配置结构
+ for version_info in versions:
+ version_id = version_info['id']
+ version_name = version_info['name']
+ config['versions'][version_id] = {
+ 'id': version_id,
+ 'name': version_name,
+ 'product_series': {}
+ }
+
+ print(f"Fetching data for {len(versions)} versions...")
+
+ # 创建任务队列
+ task_queue = queue.Queue()
+ config_lock = threading.Lock()
+
+ # 将初始任务放入队列
+ for version_info in versions:
+ task_queue.put({
+ 'type': 'product_series',
+ 'version_id': version_info['id']
+ })
+
+ # 创建工作线程(限制最大线程数为32,避免API限流)
+ num_threads = min(os.cpu_count() or 4, 32)
+ threads = []
+ for i in range(num_threads):
+ t = threading.Thread(target=worker, args=(task_queue, config, config_lock), name=f"Worker-{i}")
+ t.start()
+ threads.append(t)
+
+ # 等待所有任务完成
+ task_queue.join()
+
+ # 等待所有线程结束
+ for t in threads:
+ t.join()
+
+ # 保存配置文件
+ output_file = os.path.join(os.path.dirname(__file__), '..', '_static', 'ascend_config.json')
+ with open(output_file, 'w', encoding='utf-8') as f:
+ json.dump(config, f, ensure_ascii=False, indent=2)
+
+ print(f"\nDone! Saved to {output_file}")
+
+if __name__ == '__main__':
+ main()
diff --git a/sources/ascend/quick_install.rst b/sources/ascend/quick_install.rst
index 6aa8c589..67270505 100644
--- a/sources/ascend/quick_install.rst
+++ b/sources/ascend/quick_install.rst
@@ -1,232 +1,50 @@
快速安装昇腾环境
-================
+===============
跟随指导,在您的机器上快速安装昇腾环境。
-1. 系统要求
-----------------
-1.1 前置检查
-^^^^^^^^^^^^^
-确认昇腾AI处理器已经安装妥当
-
-.. code-block:: bash
-
- lspci | grep 'Processing accelerators'
-
-确认操作系统架构及版本
-
-.. code-block:: bash
-
- uname -m && cat /etc/*release
-
-确认Python版本
-
-.. code-block:: bash
-
- python --version
-
-
-1.2 软件要求
-^^^^^^^^^^^^^
-======== ========================================
-软件 版本
-======== ========================================
-操作系统 openEuler20.03/22.03, Ubuntu 20.04/22.04
-Python 3.7, 3.8, 3.9, 3.10, 3.11.4
-======== ========================================
-
-
-2. 环境安装
-------------------
-根据您的需求,选择合适的软件包版本:
-
-.. warning::
-
- 以下文档需要使用非root用户进行安装安装
-
.. raw:: html
+
-
安装方式
-
操作系统
-
+
版本
+
产品系列
CPU架构
-
NPU型号
-
昇腾套件版本
+
操作系统
+
安装方式
-
-
-
操作系统
-
openEuler
-
Ubuntu
+
-
-
操作系统版本
+
-
+
-
-
NPU型号
-
Atlas 300T A2
-
Atlas 300I Duo
+
-
-
昇腾套件版本
-
-
Driver
-
Firmware
+
+
-
- 2.1 安装驱动
- 2.1.1 安装依赖
-
-
-
sudo apt-get install -y gcc make net-tools python3 python3-dev python3-pip
-
-
-
-
-
sudo yum install -y gcc make net-tools python3 python3-devel python3-pip
-
-
- 2.1.2 创建驱动运行用户
-
-
备注
-
请使用命令 id HwHiAiUser 查看用户是否存在,若存在请跳过此步骤
-
-
-
-
sudo groupadd HwHiAiUser
sudo useradd -g HwHiAiUser -d /home/HwHiAiUser -m HwHiAiUser -s /bin/bash
sudo usermod -aG HwHiAiUser $USER
-
-
- 2.1.3 下载并安装
-
- 确认您的驱动是否安装成功,可以通过以下命令验证:npu-smi info,若出现以下回显信息,说明驱动安装成功。
-
-
-
+-------------------------------------------------------------------------------------------+
- | npu-smi 23.0.2 Version: 23.0.2 |
- +----------------------+---------------+----------------------------------------------------+
- | NPU Name | Health | Power(W) Temp(C) Hugepages-Usage(page)|
- | Chip | Bus-Id | AICore(%) Memory-Usage(MB) HBM-Usage(MB) |
- +======================+===============+====================================================+
- | 0 xxx | OK | 0.0 40 0 / 0 |
- | 0 | 0000:C1:00.0 | 0 882 / 15169 0 / 32768 |
- +======================+===============+====================================================+
-
-
-
-
- 2.2 安装固件
-
-
- 安装固件后,若系统出现如下关键回显信息,表示固件安装成功。
-
-
-
Firmware package installed successfully!
-
-
-
-
- 2.3 安装CANN
- 2.3.1 安装python依赖
-
-
-
pip3 install -i https://pypi.tuna.tsinghua.edu.cn/simple attrs cython numpy==1.24.0 decorator sympy cffi pyyaml pathlib2 psutil protobuf==3.20 scipy requests absl-py
-
-
- 2.3.2 下载并安装
-
- 安装CANN-toolkit后,若系统出现以下关键回显信息,表示CANN-toolkit安装成功。
-
-
-
Ascend-cann-toolkit install success.
-
-
- 2.3.3 设置环境变量
-
-
-
source /usr/local/Ascend/ascend-toolkit/set_env.sh
-
-
-
- 安装算子包后,若系统出现以下关键回显信息,表示算子包安装成功。
-
-
-
Ascend-cann-kernels install success.
-
-
-
-
- 2.3 运行Docker容器
-
- 下列命令将创建一个名为'cann-container'的Docker容器,并将设备和驱动挂载到容器中。
-
-
-
-
-
-
-1. 卸载
-----------
-**卸载CANN-toolkit**
-
-.. code-block:: bash
-
- ~/Ascend/ascend-toolkit/
/{arch}-linux/script/uninstall.sh
-
-**卸载固件**
-
-.. code-block:: bash
-
- sudo /usr/local/Ascend/firmware/script/uninstall.sh
-
-**卸载驱动**
-
-.. code-block:: bash
-
- sudo /usr/local/Ascend/driver/script/uninstall.sh