☰
基于 Qwen-Chat 的代码自动注释工具 Auto Comments:使用指南与源码原理剖析
2026/10/1 2:09:04 网站建设 项目流程
  • 人工智能
  • 大模型
  • 微调
  • LoRA
  • 模型量化
  • 本地部署
  • 模型推理服务

【免费下载链接】Qwen

The official repo of Qwen (通义千问) chat & pretrained large language model proposed by Alibaba Cloud.

项目地址:https://gitcode.com/GitHub_Trending/qw/Qwen
点击查看免费下载

本文以 Qwen 官方仓库中的examples/auto_comments.md为核心,结合examples/auto_comments.py的完整源码实现,介绍如何利用通义千问(Qwen-Chat)大模型为 Python 代码文件自动生成中文注释。读者将掌握 Auto Comments 的命令行用法、参数语义、输出文件的生成规则,并理解其"代码分块—注释生成—注释回填合并"的完整流水线设计与底层调用链,可直接复现并二次定制属于自己的代码注释工具。

一、Auto Comments 是什么

Auto Comments 是 Qwen 官方仓库(Qwen 系列模型,包括 Qwen-7B/14B/72B 及其 Chat 版本)中提供的一个使用案例:利用 Qwen-Chat 对话模型,为代码文件自动生成注释。它位于仓库的 examples/auto_comments.py,配套说明文档即 examples/auto_comments.md。

其核心工作方式是:读取一个 Python 代码文件(或递归扫描一个文件夹下的所有 Python 文件),把代码片段作为上下文发送给 Qwen-Chat,让模型"为以上代码生成细致的中文注释",随后把生成的注释按代码行回填进原始文件,最终输出一个"文件名_comments.py"的新文件——原始代码内容保持不变,只在恰当位置插入注释。

该案例展示的正是 Qwen-Chat 在代码理解与代码改写类任务上的典型应用,也可以作为"用 LLM 批量处理代码文件"这一通用流水线的参考范本。

二、环境准备与运行前提

2.1 依赖环境

运行该脚本需要先搭建 Qwen 模型的推理环境。依据仓库根目录 README.md 中的说明,推荐环境如下:

  • Python 3.8 及以上;
  • PyTorch 1.12 及以上(推荐 2.0 及以上);
  • Transformers 4.32 及以上;
  • CUDA 11.4 及以上(GPU 用户推荐)。

仓库根目录的 requirements.txt 列出的关键依赖包括:

transformers>=4.32.0,<4.38.0 accelerate tiktoken einops transformers_stream_generator==0.0.4 scipy

安装方式:

pip install -r requirements.txt

说明:Auto Comments 脚本本身只 import 了argparse、os与transformers相关模块,但加载 Qwen-Chat 模型依赖上述完整的推理环境;如果设备支持 fp16/bf16,安装 flash-attention(可选)可进一步提升效率。

2.2 模型下载说明

脚本首次运行时会通过 Hugging Face 自动下载Qwen/Qwen-7B-Chat模型与代码(trust_remote_code=True)。如果网络受限,可参考 README.md 的 "DownloadModel" 小节,先通过 ModelScope 的snapshot_download将 checkpoint 下载到本地目录,再把脚本中的"Qwen/Qwen-7B-Chat"替换为本地目录路径,例如:

from modelscope import snapshot_download model_dir = snapshot_download('qwen/Qwen-7B-Chat')

三、使用方法:命令行参数详解

Auto Comments 的使用非常简洁,直接执行:

python auto_comments.py --path 'path of file or folder'

其中auto_comments.py位于 examples/auto_comments.py。两个命令行参数由parse_args()解析(见源码第 14-19 行):

参数类型默认值说明
--pathstr'Qwen-7B/eval/evaluate_ceval.py'目标路径。可以是单个文件(目前仅支持 Python 代码文件),也可以是文件夹(会递归扫描文件夹下所有.py文件)
--regeneratestore_true 开关False是否重新生成注释。默认False,即如果目标文件对应的注释文件已经存在,脚本会直接使用缓存,不再调用模型重新生成

两个参数的行为在源码中有明确体现:

  • --regenerate采用action='store_true'(源码第 17 行),即命令行中出现该开关即为True;
  • 在deal_one_file()中(源码第 146-148 行),当regenerate=False且输出文件已存在时,会打印use cache: <comments_path>并直接返回,避免重复消耗推理资源。

命令执行入口在文件末尾:

if __name__ == '__main__': args = parse_args() print(args) transfer(args)

transfer()(源码第 175-184 行)会先实例化 QWenChat 模型,然后根据--path是文件还是目录,分别进入deal_one_file()或deal_folder()流程。

四、使用样例:输入与输出对照

4.1 执行命令

python auto_comments.py --path test_file.py

4.2 输入文件 test_file.py

假设test_file.py内容如下(原文样例):

import numpy as np import pandas as pd import seaborn as sns sns.set_theme(style="whitegrid") rs = np.random.RandomState(365) values = rs.randn(365, 4).cumsum(axis=0) dates = pd.date_range("1 1 2016", periods=365, freq="D") data = pd.DataFrame(values, dates, columns=["A", "B", "C", "D"]) data = data.rolling(7).mean() sns.lineplot(data=data, palette="tab10", linewidth=2.5)

4.3 输出文件 test_file_comments.py

脚本会在同目录下生成test_file_comments.py(命名规则见下文 5.5 节),内容如下(原文样例):

# 导入需要的库 import numpy as np import pandas as pd import seaborn as sns # 设置 Seaborn 的主题风格为白色网格 sns.set_theme(style="whitegrid") # 生成随机数 rs = np.random.RandomState(365) # 生成 365 行 4 列的随机数,并按行累加 values = rs.randn(365, 4).cumsum(axis=0) # 生成日期 dates = pd.date_range("1 1 2016", periods=365, freq="D") # 将随机数和日期组合成 DataFrame data = pd.DataFrame(values, dates, columns=["A", "B", "C", "D"]) # 对 DataFrame 进行 7 天滑动平均 data = data.rolling(7).mean() # 使用 Seaborn 绘制折线图 sns.lineplot(data=data, palette="tab10", linewidth=2.5)

可以看到:Qwen-Chat 为每行/每组代码在上方生成了对应的中文注释,同时原始代码逐字未变。这正是脚本"先让模型生成带注释的代码,再把注释回填到原始代码行上"这一设计目标的结果。

五、源码级原理剖析:完整处理流水线

examples/auto_comments.py(共 189 行)自上而下可以拆解为五个核心模块。理解这套流水线,是二次开发与参数定制的基础。

5.1 全局配置常量

MaxLine = 50 # 限制单次处理最大代码行数 SplitKey = ["\ndef "] # 自定义的切分代码标识 CodeFileType = ["py"] # 目前仅测试过对 python 文件生成注释
  • MaxLine = 50:当代码超过 50 行时,脚本会按行数切分,控制单次送入模型的代码规模;
  • SplitKey = ["\ndef "]:优先按函数定义切分(以换行加def作为分界);
  • CodeFileType = ["py"]:目前只针对.py文件生成注释,其他类型文件会被跳过。

5.2 模型封装类 QWenChat

class QWenChat(): def __init__(self): self.tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True) # use bf16 # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, bf16=True).eval() # use fp16 # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True, fp16=True).eval() # use cpu only # model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="cpu", trust_remote_code=True).eval() # use auto mode, automatically select precision based on the device. self.model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B-Chat", device_map="auto", trust_remote_code=True).eval() # Specify hyperparameters for generation self.model.generation_config = GenerationConfig.from_pretrained("Qwen/Qwen-7B-Chat", trust_remote_code=True) self.history = None def chat(self, query, system = ""): # use history # response, history = self.model.chat(self.tokenizer, query, history=self.history) # 默认不使用 history response, history = self.model.chat(self.tokenizer, query, history=None) self.history = history return response

关键点:

  • 默认采用device_map="auto"自动模式,脚本根据设备自动选择精度;注释中保留了bf16 / fp16 / CPU-only三种备选加载方式,GPU 显存充足可改bf16=True或fp16=True,无 GPU 可改device_map="cpu";
  • 显式加载GenerationConfig(生成长度、top_p等超参)以维持与模型一致的生成配置;
  • chat()默认每次以history=None单轮调用(代码注释任务无需多轮上下文),同时把返回的history保存在实例上,方便需要多轮时切换为history=self.history。

5.3 注释生成提示词 gen_code_comments

def gen_code_comments(context, model = None, **kwargs): prompt = "\n为以上代码生成细致的中文注释,注意使用合适的语法。要求必须在每个函数开头生成一段统一的函数功能注释。\n除了注释,请保证原始代码内容不变。不要返回除了注释和代码以外的其余信息,不要生成额外代码。\n" return model.chat(context + prompt)

这是整个工具的"灵魂"。提示词通过四个约束来保证输出质量:

  1. 注释语言与粒度:生成"细致的中文注释",注意语法;
  2. 函数级注释:必须在每个函数开头生成一段统一的函数功能注释(即函数 docstring 式说明);
  3. 代码保真:除了注释,原始代码内容必须不变;
  4. 输出纯净:只返回注释与代码,不生成额外信息或其他代码。

模型输出以context + prompt拼接后送入model.chat()。

5.4 长代码切分策略

为避免超出模型的单次上下文处理能力,脚本提供了两种切分方式:

# 如果代码文件过长,可以简单按照最大行数切分代码 def split_context_by_maxline(text): lines = text.split("\n") lines_len = len(lines) res = [] for i in range(MaxLine, lines_len, MaxLine): res.append("\n".join(lines[i-MaxLine:i])) if i < lines_len: res.append("\n".join(lines[i:])) return res # 如果代码文件过长,可以简单按照函数切分代码 def split_context_by_splitkey(text): blocks = text.split(SplitKey[0]) return [blocks[0]] + [SplitKey[0]+x for x in blocks[1:]]

deal_one_file()中的选用逻辑(源码第 150-158 行):

context_line = len(context.split("\n")) if context_line < MaxLine: res = gen_code_comments(context, model = model) elif SplitKey[0] not in context: context_list = split_context_by_maxline(context) res = "\n".join([gen_code_comments(context_block, model = model) for context_block in context_list]) else: context_list = split_context_by_splitkey(context) res = "\n".join([gen_code_comments(context_block, model = model) for context_block in context_list])

即:50 行以内直接整段送入模型;超过 50 行且没有函数定义时按行切分;超过 50 行且有函数定义时按def切分。各分块的注释结果最后用换行拼接。

5.5 注释回填合并 merge_code_and_comments

这是保证"原始代码不被更改"的关键模块(源码第 79-135 行)。其流程为:

  1. 逐行读取原始文件ori_lines;
  2. 跳过空白行(line.isspace()),原样保留本来就以#开头的注释行;
  3. 对每条非注释代码行,在模型生成的注释文件com_lines中通过子串匹配(line[:-1] not in com_lines[j])定位对应代码行;
  4. 从匹配行向前回溯收集注释行(up_comments),并通过triple_dot_flag状态机正确处理"""/'''形式的多行 docstring(源码第 105-117 行);
  5. 把收集到的注释行逆序(reversed(up_comments))插入到代码行上方;
  6. 若注释行含#而代码行没有,则把注释拼接到行内(" #" + com_lines[j].split("#")[-1]);
  7. 未在注释文件中匹配到的行,原样保留。

最后write_file(comments_path, "".join(res))将合并结果写回注释文件。这套合并逻辑刻意做到"以原始文件为骨架、以注释为点缀",因此即使模型在生成时对代码做了微小改动,最终落盘代码仍以原始行为准。

5.6 文件与文件夹处理

# 处理单个文件 def deal_one_file(model, path, args): context = read_file(path) fname = path.split("/")[-1] fpath = "/".join(path.split("/")[:-1]) outfname = fname.split(".")[0]+"_comments."+fname.split(".")[-1] comments_path = os.path.join(fpath, outfname) if (not args.regenerate) and os.path.exists(comments_path): print("use cache: ", comments_path) return ...
  • 输出命名规则:test_file.py→test_file_comments.py(在文件名主体后插入_comments,扩展名不变),输出与输入同目录;
  • 缓存机制:输出文件已存在且未指定--regenerate时直接复用;
  • 文件夹递归:deal_folder()(源码第 164-173 行)递归遍历子目录,仅处理扩展名在CodeFileType中且文件名不含_comments的.py文件,从而避免把已经生成过的注释文件再次处理。

六、整体调用链一览

从命令执行到输出注释文件的完整调用链为:

python auto_comments.py --path xxx │ ▼ parse_args() ──► transfer(args) │ ├─ os.path.isfile ──► deal_one_file(model, path, args) │ ├─ read_file() 读取代码 │ ├─ 判断行数 < MaxLine:直接 gen_code_comments │ ├─ 否则按 SplitKey 或 MaxLine 切分后分批生成 │ ├─ write_file() 写出模型结果 │ └─ merge_code_and_comments() 回填合并 │ └─ os.path.isdir ──► deal_folder(model, path, args) └─ 递归每个 .py 文件 ──► deal_one_file(...)

其中模型交互依赖QWenChat.chat()→model.chat(tokenizer, query, history=None),即仓库 README 中标准的 Qwen-Chat Transformers 推理方式(参见 README.md 的 Quickstart 章节,以及 cli_demo.py 中同样的加载与调用模式)。

七、适用前提与限制说明

从源码可以明确归纳出以下边界条件,使用时需注意:

  1. 语言限制:CodeFileType = ["py"],目前仅针对 Python 文件测试过;其他代码类型文件会被静默跳过(并打印Please specify a correct path!或直接不处理);
  2. 模型依赖:默认加载Qwen/Qwen-7B-Chat,首次运行需联网下载模型权重与自定义代码;可根据显存改用 bf16/fp16/CPU 模式或替换为 Qwen-14B-Chat 等更大模型(相应地调整AutoModelForCausalLM.from_pretrained中的模型名);
  3. 上下文长度:单次生成被限制在 50 行以内(MaxLine),长文件依赖切分策略,切分粒度以函数(def)优先;这两个常量MaxLine与SplitKey均可按需调整;
  4. 输出文件覆盖:默认不覆盖已有_comments文件,需强制重新生成时加--regenerate参数;
  5. 合并策略:注释回填是启发式匹配(子串匹配 + 向前回溯收集),对于模型输出中注释与代码对应关系异常的情况,合并结果可能不够理想——源码注释也明确说明"这部分可以使用各种不同的策略处理",开发者可以按自己的场景替换merge_code_and_comments的实现。

八、扩展思路

Auto Comments 虽然定位为示例,但其流水线具有很强的可移植性,基于源码可以低成本扩展出更多能力:

  • 支持多语言:把CodeFileType扩展为["py", "js", "java", "go"]等,并针对各语言的注释符号(//、/* */等)调整合并逻辑;
  • 接入更强模型:将模型名替换为Qwen/Qwen-14B-Chat或Qwen/Qwen-72B-Chat,在显存允许的前提下获得更好的注释质量;
  • 结合 vLLM 等推理框架:仓库 recipes/inference/vllm 提供了 OpenAI 风格 API 的部署方式,可将gen_code_comments中的模型调用替换为 API 请求,实现异步批量注释;
  • 作为代码理解 Agent 的组件:与仓库中function_call、React 等 Agent 示例(参见 examples/react_demo.py、examples/function_call_examples.py)组合,让模型在阅读代码前先完成注释增强,提升长代码理解能力。

九、小结

Auto Comments 是 Qwen 开源仓库中一个"小而完整"的 LLM 工程化案例:命令行参数简洁(--path+--regenerate),提示词设计精确,并配套了长代码切分、注释回填合并、缓存复用与文件夹递归等工程细节。通过本文对 examples/auto_comments.md 与 examples/auto_comments.py 的对照解读,读者不仅能立即跑通"为 Python 代码自动生成中文注释"这一场景,还能掌握其底层调用链与每处可定制点,为进一步扩展(多语言、大模型、批量化、Agent 化)打下基础。

  • 人工智能
  • 大模型
  • 微调
  • LoRA
  • 模型量化
  • 本地部署
  • 模型推理服务

【免费下载链接】Qwen

The official repo of Qwen (通义千问) chat & pretrained large language model proposed by Alibaba Cloud.

项目地址:https://gitcode.com/GitHub_Trending/qw/Qwen
点击查看免费下载
上一篇:终极指南:如何用Solaar实现Logitech设备的智能节能模式
下一篇:Sublime Markdown Extended高级用法:自定义语法高亮与主题设置

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询