ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

ESPnet2 S2T1 Recipe 实战指南:基于弱监督学习与 OWSM 范式训练多任务 Speech-to-Text 模型

ESPnet2 S2T1 Recipe 实战指南:基于弱监督学习与 OWSM 范式训练多任务 Speech-to-Text 模型 人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载本文围绕 ESPnet2 的egs2/TEMPLATE/s2t1模板S2T1 recipe展开系统讲解如何以 OpenAI Whisper 的风格用单个 encoder-decoder 模型同时完成多语言 ASR、语音翻译ST、带时间戳转录与长语音条件生成等任务。文章完整覆盖该 recipe 的 16 个处理阶段、OWSM 格式的text/text.prev/text.ctc三份文本标注体系以及从零训练 OWSM 和基于预训练 OWSM 微调自定义数据的完整实操流程。读完本文你将能够独立搭建自己的多任务语音理解训练管线并复现或微调 OWSM 系列模型。S2T1 是什么Whisper 式弱监督学习模板S2T1Speech-to-Text 1是 ESPnet2 中用于弱监督语音学习的标准 recipe 模板其设计基于 ASR1但训练范式参照 OpenAI Whisper使用特殊 token 作为任务指示符如transcribe、translate或预测目标如语言 ID让同一个 encoder-decoder 模型在多种语言、多个任务上联合训练。它进一步支持条件生成——模型可以以上一句语音的文本prompt作为生成条件从而面向长篇讲话场景。更详细的方法描述可参见 OWSM 论文ASRU 2023的 Reproducing Whisper-Style Training Using an Open-Source Toolkit and Publicly Available DataarXiv:2309.13876该论文的 BibTeX 条目也收录在本模板文档的末尾。从模板目录结构egs2/TEMPLATE/s2t1可以看到它的完整构成s2t.shrecipe 主控脚本定义 16 个阶段与全部命令行参数见下节setup.sh将模板复制/软链接到自定义数据集目录的初始化脚本conf/fbank.conf16kHz、80 维 mel 滤波组、pbs.conf、queue.conf、slurm.conf等特征与集群调度配置local/、scripts/、pyscripts/、steps/、utils/数据准备与工具脚本path.sh、cmd.sh、db.sh环境路径与运行命令本地 / SGE / SLURM配置。Recipe 的 16 个阶段总览S2T1 recipe 由 16 个阶段stage组成可通过s2t.sh的--stage N --stop_stage M精确控制执行范围阶段名称作用1Data preparation调用local/data.sh生成训练/验证集数据目录2Speed perturbation速度扰动数据增强可选3Wav format统一音频格式wav / flac / kaldi_ark4Remove long or short data过滤过长/过短语音5Generate token list用 BPE 从训练文本生成 token 词表6LM statistics collection收集 LM 训练文本形状统计NN LM 可选7LM training神经网络语言模型训练可选8LM perplexity计算 LM 困惑度PPL9Ngram LM training训练 N-gram 语言模型可选10S2T statistics collection收集 S2T 训练输入/输出文本统计11S2T training主干模型训练12S2T inference对任意测试集执行 ASR 或 ST 解码13S2T scoring计算字/词/token 级错误率14-15Pack upload可选打包模型并上传 Hugging Face各阶段在 s2t.sh 中有完整的 bash 实现阶段 6-8NN LM与阶段 9N-gram LM在--use_lm false时会被自动跳过--skip_data_prep、--skip_train、--skip_eval、--skip_packing、--skip_upload_hf等开关还会批量加入skip_stages列表最终通过排序去重后跳过对应阶段。阶段 1 详解OWSM 格式的数据准备数据准备阶段调用local/data.sh在data/下生成 Kaldi 风格的数据目录训练集与验证集。其核心在于训练文本的组织方式S2T1 采用如下带特殊 token 的格式sop prevsoscategorytaskstarttime1 utt1endtime1starttime2 utt2endtime2eos其中sop表示 prev/prompt 句子的起始 token。由于音频被固定为 30 秒长度、时间分辨率为 20ms 或 40ms时间戳也作为特殊 token 参与建模。文档给出的真实示例为sop Im going to talk today about energy and climate.sosentranscribe0.00 And that might seem a bit surprising, because my full-time work at the foundation is mostly about vaccines and seeds, about the things that we need to invent and deliver to help the poorest two billion live better lives.14.1215.36 But energy and climate are extremely important to these people; in fact, more important than to anyone else on the planet.24.26eos三份文本文件的分工数据准备阶段需要生成三份关键文本文件text目标句子本身即sos与eos之间的文本必须包含上述所有特殊 token。若数据没有时间戳则用notimestamps代替同时仍需确保nlsyms_txt非语言符号表覆盖所有可能的时间戳 token 范围——该范围在 egs2/owsm_v1/s2t1/local/utils.py 中定义为SPEECH_MAX_LEN 30、SPEECH_RESOLUTION 0.02下从0.00到30.00的全部时间戳符号。需要特别注意的是sop、sos、eos实际由预处理/数据加载阶段自动插入数据文件中只需写languagetaskstarttime1 utt1endtime1starttime2 utt2endtime2。对 ST 任务text应存放目标语言的翻译。text.prev上一句文本即sop与sos之间的内容用于条件生成。讲话开头可能没有上句此时使用特殊 tokenna表示不可用。该文件除了na外不应包含任何特殊 token。text.ctc不带任何特殊 token 的 ASR 转写文本用于 CTC 损失。对 ASR 语句可直接从text中取task与eos之间的文本去掉时间戳对 ST 语句text.ctc应包含源语言的 ASR 转写参见 egs2/owsm_v1/s2t1/local/prepare_covost2.py因而与目标语言翻译的text不同。若没有 ASR 转写则同样使用na。数据准备的注意事项文件名必须严格命名为text.prev含点号和text.ctc但在训练配置中对应的text_ctc_name等参数名使用下划线如text_ctc。若同时支持多个任务如 ASR 与 ST所有语句都应同时放入text、text.prev、text.ctc由任务 token如asr区分不同任务。若同一语音被多次使用例如分别用于 ASR 和 ST每条副本需要唯一 ID可将任务名追加到 utterance ID 上。数据切分后需用utils/fix_data_dir.sh --utt_extra_files utt2num_samples text.ctc text.prev SPLIT保证文件仍按序排列。从源码看s2t.sh 中utt_extra_filestext.prev text.ctc会被带入速度扰动、格式化、长短过滤、统计收集、训练与解码的全流程确保这三份文本始终同步处理。一个完整的 OWSM 格式数据准备实现可以参考egs2/owsm_v1/s2t1/local/下的系列脚本prepare_aishell.py、prepare_covost2.py、prepare_gigaspeech.py、prepare_librispeech.py、prepare_must-c.py、prepare_spgispeech.py、prepare_tedlium.py等以及 egs2/owsm_v1/s2t1/local/utils.py 中共享的符号定义SYMBOL_NA na、SYMBOL_NOSPEECH nospeech、时间戳符号序列与 Whisper 风格的 99 种语言代码表。阶段 2-5增强、格式统一、过滤与词表生成阶段 2速度扰动可选的训练数据增强。data/${train_set}_spXXXX 为速度因子会被生成。注意速度扰动后时间戳也必须同步改变。s2t.sh 通过scripts/utils/perturb_data_dir_speed.sh对每个因子处理且通过--utt_extra_files ${utt_extra_files} ${ref_text_files_str}保证text.prev、text.ctc等附加文本同步扰动速度因子为 1.0 时直接沿用原始目录最后用utils/combine_data.sh合并为data/${train_set}_sp。阶段 3Wav 格式统一将wav.scp中的音频统一为单一格式wav / flac / kaldi_ark。之所以需要这一步是因为 Kaldi 风格的wav.scp可能带 Unix 管道如cat /some/path |不适合直接用于训练。format_wav_scp.sh会把管道式音频转存为真实音频文件并可同时转换格式与采样率若输入已满足要求则不做任何操作。支持--feats_type raw原始波形、raw_copy跳过格式化、fbank_pitch需 Kaldi 提取 fbankpitch 特征、extracted直接使用feats.scp等多种模式训练/验证集存放在dump/raw/org/下测试集存放在dump/raw/下。阶段 4长短数据过滤对训练集与验证集移除时长过长/过短的数据--min_wav_duration默认 0.1 秒--max_wav_duration默认 30.5 秒注意 S2T 预处理会把音频 pad/trim 到 30 秒因此最长时长上限与speech_length相关同时删除空文本行awk NF ! 1最后用fix_data_dir.sh --utt_extra_files ...仅保留在所有文件中都存在的 utterance。测试集保持不变。阶段 5生成 token 列表默认使用 BPE--token_type bpe通过spm_train训练 sentencepiece 模型其中--nbpe控制词表大小、--bpemode支持 unigram 或 bpe、--bpe_input_sentence_size控制 BPE 训练输入句数默认 1 亿。生成的tokens.txt中第一个符号必须是blankCTC blank索引 0 同时被其他任务用作 ignore-index其后为unk、BPE 词条、sos、eos、sop这一顺序在 s2t.sh 中固定。此外还支持char、word、whisper_en、whisper_multilingual通过espnet2.bin.whisper_export_vocabulary导出 Whisper 词表、hugging_face通过espnet2.bin.hugging_face_export_vocabulary等 token 类型。阶段 6-9可选语言模型与 N-gramNN 语言模型对 S2T1 是可选的--use_lm false可跳过阶段 6-9阶段 6LM 统计收集按--nj并行拆分lm_train.txt与lm_dev_text调用espnet2.bin.lm_train --collect_stats true收集文本形状统计再用espnet2.bin.aggregate_stats_dirs聚合并在形状文件末尾追加 token 数维度用于 batch-bins 计数。阶段 7LM 训练通过--lm_config/--lm_args配置模型与超参借助espnet2.bin.launch支持多卡/多节点分布式训练--num_nodes、--ngpu当--num_splits_lm大于 1 时语料被拆分成子集轮流训练以降低内存占用。阶段 8LM 困惑度用espnet2.bin.lm_calc_perplexity对测试文本计算 PPL结果写入exp/.../perplexity_test/ppl。阶段 9N-gram LM用 KenLM 的lmplz训练默认 3-gram-S 20%指定内存比例再以build_binary -s转成二进制格式{n}gram.bin供解码使用。更多训练配置方法可参考仓库文档doc/espnet2_training_option.md与doc/espnet2_distributed.md。阶段 10-11S2T 统计收集与训练阶段 10统计收集按--nj并行收集语音与文本的形状信息raw类型读取wav.scpsound类型支持 wav/flac 等kaldi_ark用于 ark 格式非 raw 类型读取feats.scp。除speech外text.prev、text.ctc、text也分别注册为text_prev、text_ctc、text三个文本数据流参与统计。当--feats_normalize global_mvn时聚合出全局均值的feats_stats.npz否则可跳过汇总。最后同样为每个文本流生成追加了词表长度的*_shape.${token_type}形状文件。阶段 11S2T 训练通过--s2t_config/--s2t_args指定训练配置与覆盖参数。脚本根据feats_type决定输入类型与 fold_lengthraw 时fold_length s2t_speech_fold_length * 100默认--s2t_speech_fold_length 800文本默认--s2t_text_fold_length 150。若feats_normalizeglobal_mvn会自动追加--normalizeglobal_mvn --normalize_conf stats_file${s2t_stats_dir}/train/feats_stats.npz。训练同样经由espnet2.bin.launch启动分布式espnet2.bin.s2t_train若--s2t_ctc true则使用s2t_train_ctc对应 OWSM-CTC 变体。S2T 预处理器的底层实现训练配置中preprocessor: s2t对应的类为 espnet2/train/preprocessor.py 中的S2TPreprocessor其关键参数与文档中微调配置完全对应text_prev_name/text_ctc_name附加文本数据流名称默认text_prev/text_ctcfs采样率默认 16000na_symbol不可用符号默认naspeech_length音频统一长度秒默认 30speech_resolution时间分辨率秒默认 0.02用于将初始化静音位移换算成时间戳 token 的偏移量speech_init_silence训练时允许在语音前插入的最大静音长度秒用于数据增强text_prev_apply_prob以该概率使用上一句作为条件否则置为na训练时随机采样time_apply_prob以该概率保留时间戳否则移除并插入notimestampsnotime_symbol/first_time_symbol/last_time_symbol分别对应notimestamps、0.00、30.00。_pad_or_trim_speech将语音补零或截断到speech_length * fs个采样点并返回左侧插入的静音采样数_text_process随后根据静音量对时间戳 token 做整体平移text_ints[...] time_shift保证时间戳与音频对齐。__call__中先处理语音、再处理文本形成完整的 Whisper 式输入输出对。阶段 12-15解码、评测与打包上传阶段 12S2T inference用任意准备好的测试集执行 ASR/ST 解码。支持--gpu_inference切换 GPU/CPU 解码、--inference_nj并行数、--inference_config/--inference_args例如--lm_weight 0.1以及--use_streaming流式解码对应s2t_inference_streaming。若配置了 LM/N-gram--use_lm、--use_ngram会通过--lm_train_config、--lm_file、--ngram_file注入解码器。默认使用valid.acc.ave.pth作为解码模型可通过--inference_s2t_model指定其他 checkpoint如train.loss.best.pth、3epoch.pth、valid.loss.ave.pth。解码结果输出token、token_int、score、text、text_nospecial等文件。阶段 13S2T scoring分别按 char / word / bpe 三种 token 粒度将参考文本与text_nospecial假设文本经espnet2.bin.tokenize_text分词后用sclite计算错误率char→cer、word→wer、bpe→ter结果写入score_cer/result.txt、score_wer/result.txt、score_ter/result.txt最后通过show_asr_result.sh汇总为exp/.../RESULTS.md。阶段 14Pack用espnet2.bin.pack s2t将config.yaml、checkpoint、feats_stats.npz若 global_mvn、BPE 模型、RESULTS.md、attention 图等打包成 zip方便分享。阶段 15Upload设置hf_repo后将打包模型解压到本地 Hugging Face 仓库并生成 README模板见 egs2/TEMPLATE/s2t1/scripts/utils/TEMPLATE_HF_Readme.md经 git push 上传分享。该阶段需要git-lfs支持。如何运行从零训练 OWSM仓库已在egs2/mixed_v1、egs2/mixed_v2、egs2/mixed_v3中提供了完整的 OWSM 训练 recipe可直接参考这些目录运行多任务、多语言的弱监督训练。实战微调预训练 OWSM以 AISHELL-1 为例若想基于某个数据集微调预训练 OWSM可按以下三步进行。下面以 AISHELL-1 为例完整展开。1. 准备s2t1recipe首先把本模板复制到自定义数据集目录下egs2/TEMPLATE/s2t1/setup.sh egs2/aishell/s2t1setup.sh 会把cmd.sh、conf、local复制到目标目录并为s2t.sh、path.sh、db.sh、scripts、pyscripts、utils创建指向模板的符号链接保证脚本更新能同步到各数据集。然后下载一个预训练模型这里以espnet/owsm_v2_ebranchformer为例# go to the created dir cd egs2/aishell/s2t1 # source path.sh . ./path.sh # download model from hugging face using espnet_model_zoo_download # we use dummy names for required arguments and we do not run any actual stage (thus --stage 100) ./s2t.sh --download_model espnet/owsm_v2_ebranchformer --stage 100 --train_set dummy --valid_set dummy2 --test_sets dummy3下载的模型会保存在本地缓存中并解压exp目录会被自动创建并包含指向 checkpoint 与配置文件的符号链接。微调需要用到以下重要文件config包含全部训练参数与 token 列表的 yaml 文件名为config.yamlmodel checkpoint名为xxx.pth本例中是valid.total_count.ave_5best.till25epoch.pthstats当feats_normalize为global_mvn时用于归一化输入语音特征bpe modelsentencepiece 使用的 BPE 模型。stats 与 bpemodel 的路径都可以从config.yaml中查得grep stats_file exp/espnet/owsm_v2_ebranchformer/config.yaml grep bpemodel exp/espnet/owsm_v2_ebranchformer/config.yaml后续步骤中需要手动将这两个文件复制到正确位置。2. 按 OWSM 格式准备数据数据必须按第 1 阶段描述的 OWSM 格式准备。由于 AISHELL-1 已包含在 OWSM v1 中可直接复用其数据准备脚本自己的数据需自行编写脚本并保证语言代码等特殊 token 与预训练模型保持一致。微调时不会生成新词表而是直接沿用预训练模型的词表。cd local/ ln -s ../../../mixed_v1/s2t1/local/utils.py ./ ln -s ../../../mixed_v1/s2t1/local/prepare_aishell.* ./ cd .. # modify data_dir and execute: ./local/prepare_aishell.sh准备好的数据存放在新的data目录下。接下来编写run.sh大部分抄自 OWSM v2 recipe先运行阶段 3-4 格式化数据#!/usr/bin/env bash # Set bash to debug mode, it will exit on : # -e error, -u undefined variable, -o ... error in pipeline, -x print commands, set -e set -u set -o pipefail train_setAISHELL-1/train valid_setAISHELL-1/dev test_setsAISHELL-1/dev nbpe50000 # this should be consistent with the pre-trained model s2t_configconf/train_s2t_ebf_conv2d_size1024_e12_d12.yaml inference_configconf/decode_s2t.yaml # inference only args # --cleaner whisper_basic --hyp_cleaner whisper_basic ./s2t.sh \ --stage 3 \ --stop_stage 4 \ --use_lm false \ --num_nodes 1 \ --ngpu 4 \ --nj 32 \ --gpu_inference true \ --inference_nj 4 \ --num_splits_s2t 1 \ --feats_type raw \ --audio_format flac.ark \ --token_type bpe \ --nbpe ${nbpe} \ --bpe_input_sentence_size 10000000 \ --s2t_config ${s2t_config} \ --inference_config ${inference_config} \ --train_set ${train_set} \ --valid_set ${valid_set} \ --test_sets ${test_sets} \ --bpe_train_text dump/raw/${train_set}/text \ --bpe_nlsyms data/nlsyms.txt \ --lm_train_text dump/raw/${train_set}/text $运行./run.sh --stage 3 --stop_stage 4然后手动创建 BPE token 目录等价于阶段 5但不生成新词表mkdir -p data/token_list/bpe_unigram50000 cp path_to_bpe_model data/token_list/bpe_unigram50000 # path_to_bpe_model is in config.yaml # we extract the token list python -c import yaml; config yaml.safe_load(open(exp/espnet/owsm_v2_ebranchformer/config.yaml, r)); open(data/token_list/bpe_unigram50000/tokens.txt, w).write(\n.join(config[token_list]) )3. 微调模型创建微调用训练配置它基于原config.yaml修改而来。需要注意学习率等训练超参需要自行调优因为模型在小训练集上容易过拟合preprocessor: s2t preprocessor_conf: text_prev_name: text_prev text_ctc_name: text_ctc fs: 16000 na_symbol: na speech_length: 30 speech_resolution: 0.02 speech_init_silence: 30 text_prev_apply_prob: 0.0 # we do not use previous prompt time_apply_prob: 0.0 # we do not use any timestamp for fine-tuning notime_symbol: notimestamps first_time_symbol: 0.00 last_time_symbol: 30.00 frontend_conf: n_fft: 512 win_length: 400 hop_length: 160 specaug: specaug specaug_conf: apply_time_warp: false time_warp_window: 5 time_warp_mode: bicubic apply_freq_mask: true freq_mask_width_range: - 0 - 27 num_freq_mask: 2 apply_time_mask: true time_mask_width_ratio_range: - 0. - 0.05 num_time_mask: 10 encoder: e_branchformer encoder_conf: output_size: 1024 attention_heads: 16 attention_layer_type: selfattn pos_enc_layer_type: abs_pos rel_pos_type: latest cgmlp_linear_units: 4096 cgmlp_conv_kernel: 31 use_linear_after_conv: false gate_activation: identity num_blocks: 12 dropout_rate: 0.1 positional_dropout_rate: 0.1 attention_dropout_rate: 0.1 input_layer: conv2d layer_drop_rate: 0.0 linear_units: 4096 positionwise_layer_type: linear use_ffn: true macaron_ffn: true merge_conv_kernel: 31 decoder: transformer decoder_conf: attention_heads: 16 linear_units: 4096 num_blocks: 12 dropout_rate: 0.1 positional_dropout_rate: 0.1 self_attention_dropout_rate: 0.1 src_attention_dropout_rate: 0.1 model_conf: ctc_weight: 0.3 lsm_weight: 0.1 length_normalized_loss: false sym_na: na # NOTE: you may need to tune these hyperparams optim: adamw optim_conf: lr: 1.0e-04 betas: - 0.9 - 0.98 eps: 1.0e-06 weight_decay: 0.0 scheduler: warmuplr scheduler_conf: warmup_steps: 5000 # NOTE: we are using 4 GPUs with 48GB memory batch_type: unsorted batch_size: 16 accum_grad: 4 max_epoch: 20 patience: none init: none best_model_criterion: - - valid - acc - max - - valid - total_count - max keep_nbest_models: 5 use_amp: true num_workers: 4 unused_parameters: false seed: 2023 num_att_plot: 1 # fine-tune init_param: - exp/espnet/owsm_v2_ebranchformer/valid.total_count.ave_5best.till25epoch.pth ignore_init_mismatch: false配置要点解读preprocessor_conf中的参数与上文S2TPreprocessor一一对应text_prev_apply_prob: 0.0表示不使用上一句 prompttime_apply_prob: 0.0表示微调时不使用时间戳时间戳会被替换为notimestamps编码器采用 e_branchformer1024 输出维度、12 层、16 注意力头、conv2d 输入层解码器为 12 层 transformermodel_conf中ctc_weight: 0.3为 CTC 与注意力损失的权重配比、lsm_weight: 0.1为标签平滑、sym_na: na指定不可用符号关键微调入口是init_param指向下载的 checkpointignore_init_mismatch: false保证参数严格对齐4 卡 48GB 显存下使用batch_type: unsorted、batch_size: 16、accum_grad: 4的配置组合。接着收集语音与文本的形状统计但跳过均值和方差收集因为使用预训练模型./run.sh --stage 10 --stop_stage 10 --feats_normalize utterance_mvn --s2t_args --model_conf extract_feats_in_collect_statsfalse --batch_size 5再将预训练模型现有的均值方差复制到正确位置cp path_to_train_stats exp/s2t_stats_raw_bpe50000/train/ # path_to_train_stats is in config.yaml最后开始训练./run.sh --stage 11 --stop_stage 11训练完成后按需运行阶段 12解码、13打分、14打包即可得到微调后的模型与评测结果。相关研究引用本文所述方法的出处OWSM / Whisper 式训练复现引用信息如下article{peng2023reproducing, title{Reproducing Whisper-Style Training Using an Open-Source Toolkit and Publicly Available Data}, author{Peng, Yifan and Tian, Jinchuan and Yan, Brian and Berrebbi, Dan and Chang, Xuankai and Li, Xinjian and Shi, Jiatong and Arora, Siddhant and Chen, William and Sharma, Roshan and others}, journal{arXiv preprint arXiv:2309.13876}, year{2023} }深入阅读模板主控脚本与全部参数egs2/TEMPLATE/s2t1/s2t.shS2T 预处理器源码espnet2/train/preprocessor.pyOWSM 数据准备与符号定义egs2/owsm_v1/s2t1/local、egs2/owsm_v1/s2t1/local/utils.pyOWSM 训练完整 recipeegs2/mixed_v1、egs2/mixed_v2、egs2/mixed_v3训练配置修改与分布式训练doc/espnet2_training_option.md、doc/espnet2_distributed.md模型打包与共享doc/espnet2_tutorial.md赞分享人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载相关推荐Coze Studio 知识库 Markdown 文档解析引擎深度解析从测试样本到生产级切分实现Coze Studio 知识库 Markdown 文档解析引擎深度解析从测试样本到生产级切分实现 导读 本文围绕 coze studio 开源仓库中知识库K人工智能语音音频深度学习NLP终极Snorkel多任务学习指南如何快速构建高效弱监督训练系统终极Snorkel多任务学习指南如何快速构建高效弱监督训练系统 Snorkel是一个专注于通过弱监督快速生成训练数据的系统它允许开发者利用标签函数LF和机器学习数据标注深度学习transformers.js模型弱监督学习噪声标签下的模型训练transformers.js模型弱监督学习噪声标签下的模型训练 引言Web端AI训练的新挑战 在当今的Web应用开发中直接在浏览器中运行机器学习模型已成人工智能大模型本地部署上一篇Security-101 负责任 AIResponsible AI实战指南让 AI 系统在安全与伦理之间兼得下一篇深度解析Forza Mods AIO游戏内存修改工具的技术架构与实现原理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表