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型号
-
昇腾套件版本
+
操作系统
+
安装方式
-
-
安装方式
-
直接安装
-
Docker
-
-
-
操作系统
-
openEuler
-
Ubuntu
+
+
版本
-
-
操作系统版本
+
+
产品系列
-
+
CPU架构
-
x86-64
-
aarch64
-
-
NPU型号
-
Atlas 300T A2
-
Atlas 300I Duo
+
+
操作系统
-
-
昇腾套件版本
- -
Driver
-
Firmware
+
+
安装方式
+
- - -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