人工智能计算机视觉深度学习【免费下载链接】mmaction2OpenMMLabs Next Generation Video Understanding Toolbox and Benchmark项目地址https://gitcode.com/gh_mirrors/mm/mmaction2点击查看免费下载AVA-KineticsThe AVA-Kinetics Localized Human Actions Video Dataset是 AVA Actions 与 Kinetics 两大数据集的交叉产物通过为 Kinetics 视频片段补充时空动作标注为时空动作检测Spatio-Temporal Action Detection提供了更大规模、更多样化的训练数据。本文基于 tools/data/ava_kinetics/README.md 与仓库内配套脚本完整梳理在 MMAction2 中从零准备 AVA-Kinetics 数据集的七个步骤Kinetics700 准备、标注下载、视频裁剪、RGB 帧提取、训练标注生成、人体提案获取以及最终将 AVA 部分合并进 AVA-Kinetics。读完本文你将能够独立复现完整的数据管线并理解AVAKineticsDataset在训练阶段如何混合读取 AVA 部分的 rawframes 与 Kinetics 部分的视频从而在保持精度的前提下加速训练。1. AVA-Kinetics 数据集概览与准备工作AVA-Kinetics 由 Google Research 发布其官方引用格式为article{li2020ava, title{The ava-kinetics localized human actions video dataset}, author{Li, Ang and Thotakuri, Meghana and Ross, David A and Carreira, Jo{\~a}o and Vostrikov, Alexander and Zisserman, Andrew}, journal{arXiv preprint arXiv:2005.00214}, year{2020} }从数据集构造方式看AVA-Kinetics 是 AVA 与 Kinetics 的交叉crossover数据集其动作标注沿用 AVA 的时空定位标注体系80 类原子动作、逐帧标注人体框与动作标签而视频来源则是 Kinetics 数据集。因此准备工作通常分为两条线AVA 部分建议先按 tools/data/ava/README.md 准备妥当与Kinetics 部分本文重点。在本文随后的流程中我们会分别准备两部分最后将它们合并。关于训练阶段的读取策略官方给出的设计是AVA 部分继续从 rawframes原始帧读取Kinetics 部分则直接从视频文件读取使用decord解码以加速训练。这一点在 configs/detection/slowonly/slowonly_k400-pre-r50_8xb8-8x8x1-10e_ava-kinetics-rgb.py 等训练配置中体现为统一的数据集类型AVAKineticsDataset下文第 9 节会结合 mmaction/datasets/ava_dataset.py 的源码展开说明。开始之前请确保当前目录位于$MMACTION2/tools/data/ava_kinetics/整个数据准备流程涉及的所有 Python 脚本cut_kinetics.py、extract_rgb_frames.py、prepare_annotation.py、fetch_proposal.py、merge_annotations.py、softlink_ava.py都位于该目录下读者可直接对照仓库中的脚本原文阅读本节之后的流程说明。2. Step 1准备 Kinetics700 数据集Kinetics 部分的所有视频片段均从Kinetics-700数据集采样而来因此第一步是准备 Kinetics-700 数据。官方推荐的方式是先按照 tools/data/kinetics/README.md含 Step 4 Generate file list完成 Kinetics-700 的准备。这一步只需要视频文件不需要预先提取帧。准备完成后你将获得以下两个关键产物视频文件目录$MMACTION2/data/kinetics700/videos_train视频文件列表$MMACTION2/data/kinetics700/kinetics700_train_list_videos.txt其中文件列表的每一行格式为Path_to_video_1 label_1 Path_to_video_2 label_2 ... Path_to_video_n label_n一个关键要求是文件名中必须包含该视频片段在原始视频中的起止时间戳秒。例如class602/o3lCwWyyc_s_000012_000022.mp4 602这表示该视频片段是原始视频的第 12 到第 22 秒。MMAotion2 的cut_kinetics.py正是依赖这个命名约定来定位和裁剪标注片段。需要说明的是Kinetics 部分在下载/准备过程中可能出现个别视频缺失的情况这不会阻塞后续流程——缺失的视频会在后续步骤中被自动忽略cut_kinetics.py与prepare_annotation.py中都有对应的过滤逻辑详见下文。3. Step 2下载 AVA-Kinetics 标注在$MMACTION2/tools/data/ava_kinetics/目录下执行以下命令下载标注压缩包并解压wget https://storage.googleapis.com/deepmind-media/Datasets/ava_kinetics_v1_0.tar.gz tar xf ava_kinetics_v1_0.tar.gz rm ava_kinetics_v1_0.tar.gz解压成功后$MMACTION2/tools/data/ava_kinetics/下会出现ava_kinetics_v1_0目录。该目录中包含 Kinetics 部分的标注文件kinetics_train_v1.0.csv训练集时空标注这也是后面多个脚本的标注输入。目前仓库只使用 Kinetics 部分的训练集来扩充训练数据Kinetics 部分的验证集支持将在后续版本中加入。从源码看cut_kinetics.py 的get_kinetics_frames()会按行解析该 CSV每行按逗号切分为 7 个字段其中第 0 个字段为视频 id第 1 个字段为标注所在的时间戳秒并据此构建video_id - {时间戳集合}的查找表。4. Step 3裁剪视频cut_kinetics.py得到标注后需要从 Kinetics-700 的完整视频中找到并裁剪出含有标注的片段。这一步由 cut_kinetics.py 完成python3 cut_kinetics.py --avakinetics_anotation$AVAKINETICS_ANOTATION \ --kinetics_list$KINETICS_LIST \ --avakinetics_root$AVAKINETICS_ROOT \ [--num_workers$NUM_WORKERS ]脚本参数说明参数含义默认值avakinetics_anotationava-kinetics 标注所在目录./ava_kinetics_v1_0kinetics_listStep 1 中生成的视频文件列表路径必填若按 MMAction2 官方流程准备则为$MMACTION2/data/kinetics700/kinetics700_train_list_videos.txtavakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kineticsnum_workers裁剪视频所用的 worker 数-1即使用全部可用 CPU最终会生成约10 万100k个裁剪后的视频片段保存于$MMACTION2/data/ava_kinetics/videos/目录。同样个别视频缺失不影响流程后续步骤会自动忽略。4.1 源码级解析脚本内部做了什么结合 cut_kinetics.py 源码这个脚本的完整流程是构建标注查找表get_kinetics_frames()读取kinetics_train_v1.0.csv得到每个视频 id 的标注时间戳集合。过滤缺失视频filter_missing_videos()读取 Kinetics-700 文件列表从文件名中解析出video_id与起止秒数文件名倒数第二、第三段只保留在标注表中存在、且区间内确实含有标注帧的视频并会把起止时间收缩到标注帧附近max(start, min(frames)-2)与min(end, max(frames)2)从而尽量裁剪掉无标注的多余内容。去重处理由于同一段视频可能被归类到 Kinetics 的不同类别导致一个video_id出现在多行记录中。脚本会检测重叠区间并剔除被完全包含的冗余记录cut_kinetics.py。生成并执行 ffmpeg 命令每个片段对应一条命令模板为ffmpeg -ss %d -t %d -accurate_seek -i %s -r 30 -avoid_negative_ts 1 %s即以 30 fps 对指定时间区间做精准裁剪通过multiprocessing.Pool并行执行。失败视频校验remove_failed_video()使用decord.VideoReader检查裁剪产物——如果视频无法读取或实际帧数少于预期num_frames (time - 3/4) * fps则直接删除该文件保证进入下一步的数据都是可用的。5. Step 4提取 RGB 帧训练时 AVA 部分仍从 rawframes 读取因此需要把 Kinetics 部分裁剪出的视频也转成 RGB 帧。这一步与 Preparing AVA 中的 Step 4Extract RGB and Flow类似仓库提供了两种方式。方式一使用仓库自带的 ffmpeg 脚本python3 extract_rgb_frames.py --avakinetics_root$AVAKINETICS_ROOT \ [--num_workers$NUM_WORKERS ]参数说明参数含义默认值avakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kineticsnum_workers提取帧所用的 worker 数-1即使用全部可用 CPU从 extract_rgb_frames.py 源码看脚本会遍历videos/下所有视频为每个视频生成一条 ffmpeg 命令ffmpeg -i video -r 30 -q:v 1 frame_dir/img_%05d.jpg即以 30 fps、JPEG 质量q:v 1提取编号从img_00001.jpg开始的帧序列保存到rawframes/video_id/下并通过多进程并行执行。方式二使用 denseflow 的 build_rawframes.py如果你已经安装了 denseflow也可以使用仓库通用的 build_rawframes.py 来提取python3 ../build_rawframes.py ../../../data/ava_kinetics/videos/ ../../../data/ava_kinetics/rawframes/ --task rgb --level 1 --mixed-ext两种方式产出的目录结构一致均可被后续的prepare_annotation.py使用。6. Step 5准备训练标注prepare_annotation.py裁剪并提取帧之后需要根据 Kinetics 部分实际存在的帧把官方标注转换成训练可用的 CSV。这一步由 prepare_annotation.py 完成它会生成包含时空标注的kinetics_train.csv位于$AVAKINETICS_ROOTpython3 prepare_annotation.py --avakinetics_anotation$AVAKINETICS_ANOTATION \ --avakinetics_root$AVAKINETICS_ROOT \ [--num_workers$NUM_WORKERS]参数说明参数含义默认值avakinetics_anotationava-kinetics 标注所在目录./ava_kinetics_v1_0avakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kineticsnum_workers准备标注所用的 worker 数-1即使用全部可用 CPU6.1 源码级解析标注如何被落地到实际帧结合 prepare_annotation.py 源码脚本核心逻辑如下以FPS 30为基准遍历rawframes/下每个帧目录从目录名解析出video_id与起始秒数并用目录中实际存在的帧数len(os.listdir(frame_folder)) // FPS反推该片段的真实结束时间prepare_annotation.py。这一设计保证了标注只对实际存在的帧生效避免出现标注与数据不一致的问题。读取官方kinetics_train_v1.0.csv逐行过滤只保留那些视频 id 存在、且标注时间戳落在实际片段区间内的记录。对保留下来的记录将官方标注转换为训练格式{video_path},{frame_idx},{x1:.3f},{y1:.3f},{x2:.3f},{y2:.3f},{label},-1其中坐标被保留三位小数行尾追加-1作为 entity_id 占位字段AVA 标注的标准列格式为video_id, timestamp, x1, y1, x2, y2, label, entity_id。最终输出$AVAKINETICS_ROOT/kinetics_train.csv。7. Step 6获取人体提案fetch_proposal.py时空动作检测通常采用先检测人体、再分类动作的两阶段范式因此需要为每个标注帧提供人体检测框proposal。AVA 部分直接使用 FAIR 的 Long-Term Feature Banks 提供的预计算提案而 Kinetics 部分是新增数据需要自行检测。仓库采用 mmdetection 的Cascade R-CNN X-101-64x4d-FPN模型来生成提案python3 fetch_proposal.py --avakinetics_root$AVAKINETICS_ROOT \ --datalist$DATALIST \ --picklepath$PICKLEPATH \ [--config$CONFIG ] \ [--checkpoint$CHECKPOINT ]运行后会生成kinetics_proposal.pkl文件位于$MMACTION2/data/ava_kinetics/。参数说明参数含义默认值avakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kineticsdatalistStep 5 生成的kinetics_train.csv路径$MMACTION2/data/ava_kinetics/kinetics_train.csvpicklepath提案 pickle 文件的保存路径$MMACTION2/data/ava_kinetics/kinetics_proposal.pklconfig人体检测模型的配置文件X-101-64x4d-FPN.pycheckpoint人体检测模型的预训练权重mmdetection 官方预训练 checkpoint默认值指向 Cascade R-CNN X-101-64x4d-FPN 的 1x COCO 预训练权重7.1 源码级解析提案是如何生成的结合 fetch_proposal.py 源码脚本的核心流程为构造检测查找表prepare_det_lookup()读取kinetics_train.csv为每条标注记录的视频 id 与帧号生成proposal_id格式为{video_id},{timestamp:04d}并映射到对应的帧目录。注意这里对每个标注帧号frame_id会同时记录frame_id-1与frame_id1的邻近帧以覆盖时序采样fetch_proposal.py。按 GPU 并行检测single_worker()中调用 mmdetection 的init_detector()与inference_detector()把任务按 GPU rank 均分每个进程独立加载模型并处理各自子集。只保留人类结果从检测输出中过滤出labels 0COCO 类别中的 person再按score 0.7的置信度阈值筛选fetch_proposal.py。坐标归一化将检测框坐标除以图像宽高归一化到[0, 1]与 AVA 官方提案的存储格式保持一致每条记录为(h1, w1, h2, w2, score)五元组fetch_proposal.py。汇总输出每个 GPU 进程先写出tmp_person_{rank}.pkl主进程再合并去重为最终的kinetics_proposal.pkl。检测模型本身是一个标准的三阶段 Cascade R-CNNResNeXt-101-64x4d FPN配置见 tools/data/ava_kinetics/X-101-64x4d-FPN.py包含 80 类 COCO 分类头、三阶段Shared2FCBBoxHeadstage loss weights 依次为[1, 0.5, 0.25]、RPN 与测试阶段的 NMS 设置RPN NMS IoU 阈值 0.7RCNN NMS IoU 阈值 0.5。其 test_dataloader 指向 COCO val2017因此该文件本身也是一份可独立运行的 mmdetection 推理配置。8. Step 7合并 AVA 与 AVA-Kinetics至此 Kinetics 部分准备完毕。接下来需要把已经准备好的 AVA 数据集合并进ava_kinetics目录假设 AVA 已就绪于$MMACTION2/data/ava。注意执行以下命令时当前目录仍应为$MMACTION2/tools/data/ava_kinetics/。8.1 拷贝 AVA 标注首先把 AVA 的标注目录整体复制到ava_kinetics目录下cp -r ../../../data/ava/annotations/ ../../../data/ava_kinetics/8.2 合并标注文件与提案文件合并前请确认$MMACTION2/data/ava_kinetics/下已存在 Step 5、Step 6 生成的两个文件kinetics_train.csv与kinetics_proposal.pkl。然后运行python3 merge_annotations.py --avakinetics_root$AVAKINETICS_ROOT参数说明参数含义默认值avakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kinetics该脚本会把两个 Kinetics 部分生成的文件分别合并进 AVA 的对应文件kinetics_train.csv→ 追加合并到annotations/ava_train_v2.2.csvkinetics_proposal.pkl→ 合并到annotations/ava_dense_proposals_train.FAIR.recall_93.9.pkl从 merge_annotations.py 源码看合并前会先通过check_file()校验四个输入文件都存在缺失即抛出FileNotFoundError然后对 CSV 做文本行拼接后回写对 pickle 则加载两个 dict 后lookup.update(...)合并再回写merge_annotations.py。合并后的ava_train_v2.2.csv与ava_dense_proposals_train.FAIR.recall_93.9.pkl即成为训练数据集的标注与提案来源。8.3 合并 AVA 的 rawframes最后合并 AVA 部分的原始帧。可以拷贝/移动也可以用软链接。仓库提供脚本生成软链接python3 softlink_ava.py --avakinetics_root$AVAKINETICS_ROOT \ --ava_root$AVA_ROOT参数说明参数含义默认值avakinetics_rootava-kinetics 数据集保存目录$MMACTION2/data/ava_kineticsava_rootava 数据集保存目录$MMACTION2/data/avasoftlink_ava.py 的实现非常简洁遍历$AVA_ROOT/rawframes/下的每个帧目录在$AVAKINETICS_ROOT/rawframes/下为同名目录创建符号链接ln -s从而在不复制数据的前提下让ava_kinetics/rawframes同时覆盖 AVA 与 Kinetics 两部分的帧。软链接方式可以显著节省磁盘空间但请注意训练时数据目录需位于支持符号链接的文件系统上。8.4 最终目录结构完成上述所有步骤后$MMACTION2/data/ava_kinetics/的完整结构大致如下data/ava_kinetics ├── ava_kinetics_v1_0/ # Step 2 下载解压的官方标注 ├── videos/ # Step 3 裁剪出的 Kinetics 视频片段 ├── rawframes/ # Step 4 提取的 RGB 帧Kinetics 部分 │ └── {video_id}/img_%05d.jpg ├── kinetics_train.csv # Step 5 生成的 Kinetics 部分训练标注 ├── kinetics_proposal.pkl # Step 6 生成的人体提案 └── annotations/ ├── ava_train_v2.2.csv # 合并后的训练标注AVA Kinetics ├── ava_dense_proposals_train.FAIR.recall_93.9.pkl # 合并后的训练提案 ├── ava_val_v2.2.csv ├── ava_dense_proposals_val.FAIR.recall_93.9.pkl ├── ava_action_list_v2.2_for_activitynet_2019.pbtxt └── ...9. 使用 AVA-Kinetics 训练AVAKineticsDataset 与混合读取策略数据准备完成后即可在 MMAction2 的时空动作检测任务中直接使用。仓库在configs/detection/下提供了基于 AVA-Kinetics 的训练配置例如slowonly_k400-pre-r50_8xb8-8x8x1-10e_ava-kinetics-rgb.pySlowOnly R50 主干 AVARoIHead加载 Kinetics400 预训练权重10 轮训练。slowonly_k700-pre-r50_8xb8-16x4x1-10e-tricks_ava-kinetics-rgb.py以 Kinetics700 预训练权重初始化。vit-base-p16_videomae-k400-pre_8xb8-16x4x1-20e-adamw_ava-kinetics-rgb.py 与 vit-large-p16_videomae-k400-pre_8xb8-16x4x1-20e-adamw_ava-kinetics-rgb.pyVideoMAE ViT-Base/Large 主干20 轮 AdamW 训练。这些配置的数据集部分具有共同特征dataset_type AVAKineticsDataset data_root data/ava_kinetics/rawframes anno_root data/ava_kinetics/annotations ann_file_train f{anno_root}/ava_train_v2.2.csv proposal_file_train f{anno_root}/ava_dense_proposals_train.FAIR.recall_93.9.pkl label_file f{anno_root}/ava_action_list_v2.2_for_activitynet_2019.pbtxt即标注、提案、类别表全部来自合并后的annotations/目录而帧数据统一指向data/ava_kinetics/rawframes/——由于 AVA 部分是软链接进来的AVAKineticsDataset无需区分数据来源直接按frame_dir读取即可。9.1 源码级解析AVAKineticsDataset 如何工作AVAKineticsDataset定义于 mmaction/datasets/ava_dataset.py继承自BaseActionDataset。与标准AVADataset相比它的关键差异在于如何处理 Kinetics 片段的时序信息时间戳解析get_timestamp()ava_dataset.py约定长度为 11 的 video id 视为 AVA 原生的 YouTube 视频 id如0f39OWEqJ24使用默认的timestamp_start/timestamp_end源码默认 900~1800即 AVA 标注的 15~30 分钟区间而 Kinetics 片段的 id 形如{video_id}_{start}_{end}可从文件名直接解析出片段起止秒数。shot_info 计算shot_info (1, (end - start) * self._FPS 1)fps默认 30与前面所有提取脚本使用的 30 fps 严格对齐保证帧索引计算一致。提案键兼容get_data_info()中ava_dataset.py区分了两类img_key——长度 16 的键AVA 原生 id 4 位时间戳如0f39OWEqJ24,0902直接使用否则会去掉video_id中的_start_end后缀拼回{vid},{timestamp:04d}形式再去提案 dict 中查找。这正是 Step 6 生成kinetics_proposal.pkl时 key 的格式二者一一对应。缺失提案兜底若某帧在提案表中找不到则回退为整图提案[[0, 0, 1, 1]]、score 为 1ava_dataset.py。提案过滤person_det_score_thr默认 0.9可通过AVAKineticsDataset的构造参数覆盖并受num_max_proposals默认 1000上限约束。9.2 关于AVA 读帧、Kinetics 读视频的说明README 开篇提到训练时会用decord直接读取 Kinetics 部分的视频以加速训练。不过需要说明的是当前仓库在 configs/detection/ 的 AVA-Kinetics 配置中data_root均指向data/ava_kinetics/rawframes训练管线使用RawFrameDecode统一解码帧目录同时cut_kinetics.py、remove_failed_video()与fetch_proposal.py的帧定位逻辑都依赖 30 fps 的帧序列。因此在现有仓库实现下Kinetics 部分的视频videos/目录主要服务于帧提取与提案生成阶段而实际训练读取的是统一的 rawframes。如果你希望真正以AVA 读帧 Kinetics 读视频的混合模式训练需要基于AVAKineticsDataset自行扩展视频解码管线——videos/目录和配套的命名约定{video_id}_{start}_{end}.mp4已经为这种扩展保留了完整信息。这一点属于从当前仓库代码结构推断出的设计意图实际使用请以仓库内现成配置为准。10. 流程总览与常见问题10.1 七步流程速览步骤操作脚本/命令产出Step 1准备 Kinetics700视频 文件列表参考 tools/data/kinetics/README.mdvideos_train/、kinetics700_train_list_videos.txtStep 2下载官方标注wgettar xfava_kinetics_v1_0/Step 3裁剪标注片段cut_kinetics.pyvideos/约 100k 段Step 4提取 RGB 帧extract_rgb_frames.py或build_rawframes.pyrawframes/{video_id}/img_%05d.jpgStep 5生成训练标注prepare_annotation.pykinetics_train.csvStep 6生成人体提案fetch_proposal.pykinetics_proposal.pklStep 7合并 AVAmerge_annotations.pysoftlink_ava.py合并后的annotations/与rawframes/10.2 常见问题与注意事项磁盘占用约 10 万段视频的帧序列占用空间可观。官方提示若存储不足后续会提供替代的视频准备方案当前也可优先考虑保留videos/并在合并 AVA 帧时使用softlink_ava.py的软链接方案来节省空间。时间戳命名不可省略Kinetics 文件列表与裁剪产物都依赖文件名中的起止秒数*_s_000012_000022.mp4或{video_id}_000012_000022.mp4手动修改命名会导致后续脚本解析失败。帧率一致性cut_kinetics.py、extract_rgb_frames.py、prepare_annotation.py与AVAKineticsDataset的fps参数均以 30 fps 为基准任何环节的帧率偏差都会造成标注与帧错位。缺失视频可容忍Kinetics 下载常有个别视频失效所有脚本均已内置过滤逻辑缺失的样本会在裁剪、标注过滤、提案生成等环节被自动跳过不会中断流程。提案生成需要 GPUfetch_proposal.py按 GPU 数并行--num_gpus默认 8需要安装 mmdetection 并准备对应版本的预训练权重。11. 总结本文以 tools/data/ava_kinetics/README.md 为主线结合仓库中 6 个数据准备脚本与AVAKineticsDataset的实现完整梳理了 MMAction2 中 AVA-Kinetics 数据集的构建流程从 Kinetics700 视频清单出发经过官方标注下载、基于时间戳的 ffmpeg 精准裁剪、30 fps RGB 帧提取、实际帧驱动的训练标注生成、Cascade R-CNN 人体提案获取到最后与 AVA 数据集的标注/提案/帧三合一。理解这一流程不仅可以直接复现数据管线并训练 configs/detection/ 下现成的 SlowOnly、VideoMAE 时空检测模型也能为自定义的大视频 精标注混合数据集准备方案提供完整参考。赞分享人工智能计算机视觉深度学习【免费下载链接】mmaction2OpenMMLabs Next Generation Video Understanding Toolbox and Benchmark项目地址https://gitcode.com/gh_mirrors/mm/mmaction2点击查看免费下载相关推荐mmaction2 实战AVA 时空动作检测数据集完整准备指南标注、视频、抽帧、Proposal 全流程mmaction2 实战AVA 时空动作检测数据集完整准备指南标注、视频、抽帧、Proposal 全流程 本篇技术指南聚焦 OpenMMLab 视频理解工人工智能计算机视觉深度学习mmaction2 数据集准备指南AVA 时空动作检测数据的完整下载与预处理流程mmaction2 数据集准备指南AVA 时空动作检测数据的完整下载与预处理流程 AVAAtomic Visual Actions是一个面向时空动作检测人工智能计算机视觉深度学习MMagic 中 DF2K_OST 数据集准备全流程指南裁剪、标注与 LMDB 加速MMagic 中 DF2K_OST 数据集准备全流程指南裁剪、标注与 LMDB 加速 导读 本文是 MMagicOpenMMLab 多模态生成工具箱中 D媒体生成计算机视觉深度学习人工智能大模型上一篇Salt 并发渲染竞态修复HighState 活动栈按执行上下文隔离的深入剖析下一篇Slither JSON 输出格式完全指南从 detectors 结果到 upgradeability 检查创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考