执行摘要
- 一句话:统一文档生成方式为 gen-files
- 推荐动作:值得精读,尤其是
generated_content.py 的设计和 fill_markers 的严格校验理念;涉及文档自动化的团队可学习 gen-files 插件的使用模式。
功能与动机
PR body 指出之前文档生成方法混杂(mkdocs hooks + pre-commit hooks),维护困难。通过统一到 gen-files,简化构建流程,减少 git 跟踪的生成内容,并使 CLI 帮助文本与文档同步。
实现拆解
实现拆解分以下步骤:
- 新增文档生成核心库
generated_content.py,提供 fill_markers 函数,支持在文档源页中通过 --8<-- "gen:<key>" 标记插入生成内容,避免 pymdownx.snippets 的隐式行为。
- 将原本在
docs/mkdocs/hooks/ 下的 generate_argparse.py、generate_metrics.py、generate_examples.py 重命名搬迁到 docs/mkdocs/gen_files/,并改造成 gen-files 脚本:去掉 on_startup 函数封装,直接在模块作用域执行生成逻辑;将内容写入替换为 mkdocs_gen_files.open;从写独立文件改为调用 fill_markers 填充标记。
- 将原本作为 pre-commit 钩子的
tools/pre_commit/generate_attention_backend_docs.py 搬迁到 docs/mkdocs/gen_files/generate_attention_backends.py,移除 is_relevant_file 和 RELEVANT_PATTERNS 等预提交逻辑,改用 fill_markers 将生成的表格嵌入 docs/design/attention_backends.md。
- 修改
docs/mkdocs/hooks/url_schemes.py,增加 replace_docs_link 方法,将 docs.vllm.ai 绝对链接重写为相对链接,并处理 vllm.config.<Class> API 引用转换为 mkdocstrings 交叉引用。
- 调整
mkdocs.yaml 配置,注册 gen-files 插件并移除不再需要的生成文件路径;同步删除旧的 .inc.md 文件和 pre-commit 钩子配置。
- 更新
vllm/entrypoints/cli/ 下的入口文件(mm_processor.py、launch.py),添加 DESCRIPTION 和子命令注册,使 CLI 帮助文本完整,以便 gen-files 能生成准确的 CLI 参考。
关键文件:
docs/mkdocs/gen_files/generate_argparse.py(模块 文档生成;类别 source;类型 rename-or-move;符号 on_startup, format_help, linkify_docs_urls, child_link): 核心生成脚本,重命名自 docs/mkdocs/hooks/generate_argparse.py,改造成 gen-files 脚本,负责生成 CLI 参考页面。
docs/mkdocs/gen_files/generated_content.py(模块 文档生成;类别 source;类型 dependency-wiring;符号 fill_markers): 新增核心模块,提供 fill_markers 函数,是统一生成机制的基石。
docs/mkdocs/hooks/url_schemes.py(模块 文档生成;类别 source;类型 core-logic;符号 replace_docs_link): 扩展 URL 方案预处理,新增 docs.vllm.ai 绝对链接重写和 API 引用转换,确保生成页面中链接正确。
docs/mkdocs/gen_files/generate_attention_backends.py(模块 文档生成;类别 source;类型 rename-or-move;符号 generate_markdown_table, generate_usage_section, generate_priority_section, _priority_block): 重命名自 tools/pre_commit/generate_attention_backend_docs.py,从 pre-commit 钩子改为 gen-files 脚本,使用 fill_markers 生成 attention backends 特性表格。
docs/mkdocs/gen_files/generate_metrics.py(模块 文档生成;类别 source;类型 rename-or-move;符号 on_startup): 重命名自 docs/mkdocs/hooks/generate_metrics.py,改为 gen-files 脚本,使用 fill_markers 将指标表格嵌入使用页面。
关键符号:fill_markers, replace_docs_link, format_help, linkify_docs_urls, child_link, generate_markdown_table, generate_usage_section, generate_priority_section, generate_legend, _feature_table, generate_mla_section, on_startup
关键源码片段
docs/mkdocs/gen_files/generated_content.py
新增核心模块,提供 fill_markers 函数,是统一生成机制的基石。
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
"""
Inline build-time generated content into existing docs pages.
Source pages mark where generated content goes with a snippet-style marker,
`--8<-- \"gen:<key>\"`, so the insertion point is explicit and readable.
The substitution happens here (at gen-files time, before mkdocs-gen-files
shadows the page), not via pymdownx.snippets, so the content can be
generated at build time without living in a real file on disk.
The `gen:` prefix keeps these markers distinct from real pymdownx.snippets
includes, and `fill_markers` fails loudly if a marker is missing or left
behind (pymdownx.snippets would otherwise silently drop an unsubstituted
marker).
"""
from pathlib import Path
import mkdocs_gen_files
import regex as re
DOCS_DIR = Path(__file__).parent.parent.parent
_MARKER = '--8<-- "gen:{key}"'
_ANY_MARKER = re.compile(r'--8<-- "gen:[^"]*"')
def fill_markers(doc_path: str, blocks: dict[str, str]) -> None:
"""Replace `--8<-- "gen:<key>"` markers in a docs page with generated content.
Args:
doc_path: Docs-relative path of the source page to fill.
blocks: Mapping of marker key to the markdown to insert in its place.
Raises:
FileNotFoundError: If the source page does not exist.
ValueError: If an expected marker is missing, or any `gen:` marker
is left unsubstituted after filling.
"""
source = DOCS_DIR / doc_path
if not source.exists():
raise FileNotFoundError(
f"Cannot fill markers in missing page: {doc_path}"
)
text = source.read_text()
# 逐个替换标记为对应的生成内容
for key, content in blocks.items():
marker = _MARKER.format(key=key)
if marker not in text:
raise ValueError(
f"{doc_path}: missing marker {marker}"
)
text = text.replace(marker, content)
# 严格检查是否还有未替换的 gen: 标记
if leftover := _ANY_MARKER.search(text):
raise ValueError(
f"{doc_path}: unsubstituted marker {leftover.group()}"
)
# 通过 mkdocs_gen_files 写入虚拟文件
with mkdocs_gen_files.open(doc_path, "w") as f:
f.write(text)
# 让编辑按钮指向真实源页(而不是虚拟路径)
mkdocs_gen_files.set_edit_path(doc_path, doc_path)
docs/mkdocs/hooks/url_schemes.py
扩展 URL 方案预处理,新增 docs.vllm.ai 绝对链接重写和 API 引用转换,确保生成页面中链接正确。
class UrlSchemesPreprocessor(Preprocessor):
def run(self, lines):
page = self.ext.page
files = self.ext.files
if page is None:
return lines
# 定义替换函数
def replace_docs_link(match: re.Match) -> str:
"""Rewrite absolute docs.vllm.ai links as doc-relative links."""
title = match.group("title")
path = match.group("path").rstrip("/")
fragment = match.group("fragment") or ""
# vllm.config.<Class> API reference -> mkdocstrings cross-reference
if path == "api/vllm/config" and re.fullmatch(
r"#vllm\.config\.\w+", fragment
):
ident = fragment[1:]
return f"[`{ident}`][{ident}]"
# 其他文档页 -> 相对于当前页面的链接
src = f"{path.removesuffix('.html')}.md"
if files.get_file_from_path(src) is None:
return match.group(0) # 未知页面,保留原链接
rel = posixpath.relpath(src, posixpath.dirname(page.file.src_uri))
if title.startswith("http"):
title = path.rstrip("/").split("/")[-1].replace("-", " ").title()
title += fragment.replace("#", " § ").replace("-", " ").title()
return f"[{title}]({rel}{fragment})"
# 对每行应用替换
lines = [docs_link.sub(replace_docs_link, line) for line in lines]
# ... 其他替换 ...
return lines
评论区精华
PR 得到 1 个 approve 评论(来自 DarkLight1337),无其他讨论或争议。
风险与影响
- 风险:风险较低。主要影响文档构建流程,gen-files 插件配置错误可能导致文档缺失或构建失败。但作者已验证预览页面(metrics、engine_args、attention_backends、CLI 均正常)。不涉及运行时逻辑,对用户无影响。
fill_markers 对标记严格校验,若源文档中标记丢失或残留会报错,但这也避免了静默缺失。
- 影响:对用户:文档浏览体验不变,但生成内容(如表、参数列表)保持与代码同步更可靠。对系统:不再需要在 git 中跟踪
docs/generated/ 下的文件,构建时不需要 pre-commit 钩子。对团队:文档生成逻辑统一在 docs/mkdocs/gen_files/ 下,维护更简单;添加新生成页面时可复用 generated_content.py 的 fill_markers。
- 风险标记:文档构建变更, 无运行时影响, 构建失败风险低
关联脉络
参与讨论