Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[submodule "_repos/verl"]
path = _repos/verl
url = https://github.com/volcengine/verl.git
branch = main
[submodule "_repos/LLaMA-Factory"]
path = _repos/LLaMA-Factory
url = https://github.com/the-seeds/LLaMA-Factory-Doc.git
Expand Down
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ ONNXRUNTIME_CANN_MD_LOCAL := sources/_generated/sources/onnxruntime/quick_start.
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile copy-docs clean-submodules fetch-config sync-onnxruntime-doc
.PHONY: help Makefile copy-docs clean-submodules fetch-config sync-onnxruntime-doc init-submodules

# Fetch ascend config (always run to ensure freshness)
.PHONY: $(ASCEND_CONFIG)
Expand All @@ -58,13 +58,13 @@ sync-onnxruntime-doc:
@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..."
@git submodule update --init
# Initialize submodules (always run to handle empty dirs left by git clone)
init-submodules:
@git submodule sync --recursive
@git submodule update --init --remote

# Copy documentation from submodules
copy-docs: _repos/verl _repos/VeOmni _repos/LLaMA-Factory _repos/ms-swift
copy-docs: init-submodules
@echo "Preparing generated docs directory..."
@mkdir -p $(GENERATED_DOCS)

Expand Down
2 changes: 1 addition & 1 deletion _repos/verl
Submodule verl updated from 07d403 to 77476a
32 changes: 31 additions & 1 deletion _static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -362,4 +362,34 @@ body.onnxruntime-quickstart-page .rst-content .highlight {
}


/* card-icon 样式已移至 index.rst 中统一管理 */
/* =========================================================
独立社区侧边栏专属样式
========================================================= */

#independent-sidebar .custom-sidebar-caption {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
font-size: 85%;
color: #0066cc;
font-weight: 700;
text-transform: uppercase;
margin-top: 1.5em;
margin-bottom: 0.5em;
padding-left: 15px;
letter-spacing: 0.5px;
}

#independent-sidebar ul {
margin-bottom: 0 !important;
}

/* 覆盖菜单基础项的 padding,使其靠左贴齐 */
#independent-sidebar ul li.toctree-l1 > a {
padding-left: 15px !important;
}

#independent-sidebar ul li.toctree-l1.current > a {
background: #e6f0fa; /* 当前选中项高亮背景色 */
color: #0066cc;
border-left: 4px solid #0066cc;
padding-left: 11px !important; /* 减去边框宽度保持对齐 */
}
118 changes: 118 additions & 0 deletions _templates/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{% extends "!layout.html" %}

{% block menu %}
{% if is_independent %}
<!-- 1. 将原本庞大的全局菜单隐藏起来,作为数据源 -->
<div id="temp-menu-holder" style="display: none;">
{{ super() }}
</div>

<!-- 2. 独立站点独立侧边栏容器(直接插入在原菜单位置) -->
<div id="independent-sidebar"></div>

<script>
document.addEventListener('DOMContentLoaded', function() {
const mapping = {{ comm_config.get('sidebar_mapping', {}) | tojson | safe }};
const commId = '{{ current_community_id }}';

// 获取数据源和目标容器
const globalMenu = document.getElementById('temp-menu-holder');
const targetContainer = document.getElementById('independent-sidebar');

if (!globalMenu) return;

// 步骤 A: 找到当前社区的主节点 (通常带有 .current 类)
let activeL1 = globalMenu.querySelector('li.toctree-l1.current');

// 兜底策略: 如果没有 .current (如强制刷新等边缘情况),通过链接匹配
if (!activeL1 || !activeL1.querySelector('a').href.includes('/sources/' + commId + '/')) {
const links = globalMenu.querySelectorAll('li.toctree-l1 > a');
for (let i = 0; i < links.length; i++) {
if (links[i].href.includes('/sources/' + commId + '/')) {
activeL1 = links[i].closest('li');
break;
}
}
}

if (activeL1) {
// 步骤 B: 找到属于这个社区的所有子页面 (<ul>)
const subMenu = activeL1.querySelector('ul');

if (subMenu && subMenu.children.length > 0) {
let currentGroup = null;
let currentUl = null;

// 步骤 C: 遍历所有的子页面,将它们分组并插入到独立侧边栏中
const items = Array.from(subMenu.children);
items.forEach(item => {
if (item.tagName.toLowerCase() !== 'li') return;

const link = item.querySelector('a');
if (!link) return;

const fullUrl = link.href;
let matchedFolder = null;

// 匹配 conf.py 中配置的文件夹路径
// 使用更精确的匹配:sources/{commId}/{folder}/ 或 sources/_generated/sources/{commId}/{folder}/
for (const folder in mapping) {
const pattern1 = `/sources/${commId}/${folder}/`;
const pattern2 = `/sources/_generated/sources/${commId}/${folder}/`;
if (fullUrl.includes(pattern1) || fullUrl.includes(pattern2)) {
matchedFolder = folder;
break;
}
}

// 如果有的文件放在根目录没匹配到,归入 default
if (!matchedFolder) {
matchedFolder = currentGroup || 'default';
}

// 步骤 D: 遇到新分组时,创建大标题和新的 <ul>
if (currentGroup !== matchedFolder) {
if (mapping[matchedFolder]) {
const caption = document.createElement('p');
caption.className = 'caption custom-sidebar-caption';
caption.innerHTML = `<span class="caption-text">${mapping[matchedFolder]}</span>`;
targetContainer.appendChild(caption);
}

currentUl = document.createElement('ul');
targetContainer.appendChild(currentUl);
currentGroup = matchedFolder;
}

// 步骤 E: 智能动态提升整棵树的级数,完美支持长文档的内部 H2/H3 目录显示
// 找出该节点及其内部所有的级联列表项
const allTocItems = [item, ...item.querySelectorAll('[class*="toctree-l"]')];
allTocItems.forEach(el => {
// 将 toctree-l(X) 动态替换为 toctree-l(X-1)
el.className = el.className.replace(/toctree-l(\d+)/g, function(match, level) {
const newLevel = parseInt(level, 10) - 1;
return 'toctree-l' + newLevel;
});
});

// 挂载到对应独立社区的菜单中
if (currentUl) {
currentUl.appendChild(item);
}
});

// 步骤 F: 彻底删除隐蔽的全局菜单
globalMenu.remove();
return;
}
}

// 异常兜底: 如果出现极端的解析失败(比如网络延迟),取消隐藏,确保文档菜单可用
globalMenu.style.display = 'block';
});
</script>
{% else %}
<!-- 非独立社区页面,直接按普通 Sphinx 逻辑渲染 -->
{{ super() }}
{% endif %}
{% endblock %}
67 changes: 66 additions & 1 deletion conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,32 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'recommonmark',
'sphinx.ext.autodoc',
'sphinxext.remoteliteralinclude',
'sphinx_copybutton',
'sphinx_markdown_tables',
"sphinx_design",
'myst_parser',
]

# 这一行非常重要,它允许 MyST 处理复杂的标题层级
myst_heading_anchors = 3

# 允许在 RST 中嵌入 Markdown 内容
myst_enable_extensions = [
"colon_fence",
"html_image",
]

# conf.py
html_theme_options = {
# 仅显示当前页面所属的导航树,不显示全局无关节点
'collapse_navigation': True,
'navigation_depth': 4,
'includehidden': True,
'titles_only': False,
}

# 模板路径设置
templates_path = ['_templates']
autosummary_generate = True
Expand Down Expand Up @@ -180,6 +198,53 @@ def generate_api_doc():
with open(rst_filename, 'w', encoding='utf-8') as f:
f.write(rendered_content)

# =========================================================
# 独立社区页面全局配置 (核心机制:高度可配置化)
# =========================================================
html_context = {
'independent_communities': {
'verl': {
'display_name': 'verl',
'sidebar_mapping': {
'quick_start': '🚀 快速入门',
'features': '📚 特性指南',
'profiling': '⚡ 调优指南',
'examples': '📊 应用与调优实践',
'faq': '🔆 故障排查(FAQ)',
'contribution_guide': '🔧 开源开发'
}
},
}
}

# 【新增核心代码】:Sphinx 页面上下文注入 Hook
def update_page_context(app, pagename, templatename, context, doctree):
"""
拦截页面渲染,判断当前路径是否属于独立社区。
如果是,向 Jinja 模板注入 is_independent 和对应的 comm_config 变量。
支持两种路径格式:
- sources/verl/... (手写页面)
- sources/_generated/sources/verl/... (从子模块拉取的页面)
"""
communities = context.get('independent_communities', {})
context['is_independent'] = False

for comm_id, comm_info in communities.items():
# 匹配两种路径格式
if pagename.startswith(f"sources/{comm_id}") or pagename.startswith(f"sources/_generated/sources/{comm_id}"):
context['is_independent'] = True
context['current_community_id'] = comm_id
context['comm_config'] = comm_info
break

def setup(app):
app.add_css_file('custom.css')
app.add_js_file('package_info.js')
app.add_js_file('statistics.js')

# 【新增 Hook 注册】
app.connect('html-page-context', update_page_context)

# 在 Sphinx 构建之前调用该函数生成 API 文档
try:
generate_api_doc()
Expand Down
2 changes: 1 addition & 1 deletion index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@
<div class="project-card">
<div class="card-top"><div class="card-icon" style="background-image: url('_static/images/volcano.png')"></div><h3 class="card-title">verl</h3></div>
<p class="card-desc">用于 LLM 的强化学习训练库,适配昇腾并行计算方案。</p>
<div class="card-footer"><a href="https://github.com/volcengine/verl">官方链接</a><span class="split">|</span><a href="sources/_generated/sources/verl/ascend_quick_start.html">安装指南</a><span class="split">|</span><a href="sources/_generated/sources/verl/ascend_quick_start.html">快速上手</a></div>
<div class="card-footer"><a href="https://github.com/volcengine/verl">官方链接</a><span class="split">|</span><a href="sources/_generated/sources/verl/quick_start/ascend_quick_start.html">安装指南</a><span class="split">|</span><a href="sources/_generated/sources/verl/quick_start/ascend_quick_start.html">快速上手</a></div>
</div>

</div>
Expand Down
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ 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; sys_platform == "linux"
torch_npu==2.5.1rc1;sys_platform == "linux"
myst_parser
Loading
Loading