首页/新闻资讯/正文详情

ESPnet OWSM-CTC v3.1 实战指南:encoder-only 多任务语音基础模型的数据格式、训练配置与 CTC 推理

发布时间:2026/9/25 7:19:32 来源:云帆数科 栏目:资讯中心
ESPnet OWSM-CTC v3.1 实战指南:encoder-only 多任务语音基础模型的数据格式、训练配置与 CTC 推理
人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载本篇技术指南围绕 ESPnet 仓库中 OWSM-CTC v3.1 s2t1 recipe 展开OWSM-CTC 是一个基于层级多任务自条件 CTChierarchical multi-task self-conditioned CTC的 encoder-only 语音基础模型用 18 万小时公开音频训练覆盖多语言语音识别ASR、任意语言对语音翻译any-to-any ST与语种识别LID。读完后你将掌握OWSM-CTC 训练数据的目录结构与三种文本文件text/text.ctc/text.prev的精确格式、从 encoder-decoder 版 OWSM v3.1 数据到 CTC 数据的转换方法、1B 规模模型的完整训练配置train_s2t_multitask-ctc_ebf27_conv2d8_size1024.yaml以及Speech2Text的短音频 best-path 解码、decode_long长音频缓冲解码和CTCSegmentation强制对齐三套推理用法。1. 模型定位与 recipe 目录结构OWSM-CTC 继承了 Open Whisper-style Speech ModelOWSM 的多任务设计但把 encoder-decoder 结构换成了纯 encoder CTC 输出的架构从而在保持多任务能力ASR/ST/LID的同时获得 CTC 解码的速度优势——单次前向即可得到 best-path 文本无需自回归搜索也天然支持高效强制对齐。recipe 目录egs2/owsm_ctc_v3.1/s2t1/的组织如下路径作用run.sh一键训练入口调用./s2t.sh并指定数据集、BPE 规模、训练/推理配置s2t.sh15 阶段流水线脚本数据准备 → BPE 训练 → 统计量收集 → 训练 → 解码评测 → packing → HF 上传conf/train_s2t_multitask-ctc_ebf27_conv2d8_size1024.yaml1B 模型的训练配置conf/decode_s2t.yaml解码配置含lang_sym/task_sym默认值local/convert_owsm_data.py将 OWSM encoder-decoder 数据转换为 CTC 数据格式的脚本scripts/format_wav_scp.sh、evaluate_asr.sh、evaluate_asr_bleu.sh等工具脚本run.sh 中的实际训练参数为训练集train_v3、验证/测试集dev_v3、BPE 词表nbpe50000、--use_lm falseCTC 模型不使用 LM、--num_nodes 16 --ngpu 4共 64 卡与配置文件首行注释一致、--num_splits_s2t 12训练数据切分为 12 分片、--feats_type raw --audio_format flac.arkBPE 用--bpe_input_sentence_size 15000000并对data/nlsyms.txt中的非语言符号做保护--bpe_nlsyms。2. 训练数据格式text、text.ctc、text.prev2.1 数据准备流程README 明确指出训练数据格式与 encoder-decoder 版 OWSM v3.1 相同唯一区别是text文件中去掉了时间戳 token。因此数据准备的推荐路径是两步先按 egs2/owsm_v3.1/s2t1 recipe 准备 OWSM 数据再运行python local/convert_owsm_data.py把text转成新格式脚本中 BPE tokenizer 路径需改成你自己的路径。convert_owsm_data.py 的实现逻辑可以印证这一点它用build_tokenizer(token_typebpe, ...)加载 50000 词表的bpe.model与tokens.txt然后逐行把参考文本重新 tokenize 成 token id过滤掉落在0.00到30.00时间戳 token id 区间内的一切 token即 30 秒窗口内的时间戳符号再把剩余 token 还原为文本写回。脚本对dump/raw/train_v3和dump/raw/dev_v3两个数据目录做处理并把原text重命名为text.old保留备份。2.2 数据目录文件说明准备完成后的数据目录dump/raw/set包含以下文件dump/raw/train ├── feats_type ├── spk2utt ├── text ├── text.ctc ├── text.prev ├── utt2spk ├── wav.scp各文件的含义feats_type单行文本数据准备阶段自动生成内容为raw表示使用原始波形而非预提取特征spk2utt/utt2spk与标准 Kaldi recipe 相同可参考asr1recipe。由于通常不使用说话人信息每条 utterance 的 speaker ID 就是它自己的 utterance IDwav.scp标准 Kaldi 格式text多任务参考文本ASR 或 ST包含语种 token 和任务 token但不含时间戳AIDATATANG_200ZH_T0055G0013S0001_000000000_000003561_zho_asr zhoasr 今天什么日子 GigaST_YOU0000009624_002208970_002218840_en_st_zh engst_zho 大会结束后,我们要求有兴趣进一步参与我们项目或进一步参与气候教育的学生站出来, MLS_en_sikhreligion6_22_macauliffe_64kb_003555300_000003561_eng_asr engasr it farid considered that faqiri or holiness consisted in four things ...即行格式为utt_id lang_symtask_sym target_text任务 token 如asr、st_zho源英语 → 目标中文翻译体现了任意到任意翻译的标注方式text.ctc纯 ASR 参考文本不带任务前缀。注意对 ST 样本这里放的是源语言转写因为 CTC 分支的监督信号是源音频对应的 ASR 文本AIDATATANG_200ZH_T0055G0013S0001_000000000_000003561_zho_asr 今天什么日子 CoVoST2_..._en_st_ca He appointed military officers to most leading government positions.text.prev用于自条件self-conditioned机制的前一句提示文本prev/prompt无提示的样本用nanot available占位AIDATATANG_200ZH_T0055G0013S0001_000000000_000003561_zho_asr na GigaST_YOU0000009624_002208970_002218840_en_st_zh 与员工和同事一起这将有助于为事物创造空间帮助为我们创造空间一些掩护尝试新事物这套text.prev机制与训练配置中的na_symbol: na、text_prev_apply_prob: 0.5对应——训练时只有 50% 的样本真正注入前文 prompt其余以na屏蔽使模型在有无上下文两种条件下都能解码推理时decode_long的condition_on_prev_text参数即走这条 encoder-decoder 路径CTC-only 模型不启用。流水线侧也能看到对这三个文件的专门处理s2t.sh 第 331 行定义了utt_extra_filestext.prev text.ctcStage 3/4 在拷贝数据目录、按时长过滤min_wav_duration0.1、max_wav_duration30.5秒和fix_data_dir.sh对齐 utt 列表时都会把这两个附加文件同步过滤、保留保证各文件 utt id 严格一致。3. 训练配置解析1B 模型v3.1 官方模型 由 conf/train_s2t_multitask-ctc_ebf27_conv2d8_size1024.yaml 训练注释标明在 64 张 A10040GB上训练约 300 小时。关键配置按模块拆解输入与预处理preprocessor: s2t_ctc preprocessor_conf: na_symbol: na speech_length: 30 # 固定 30 秒窗口 speech_init_silence: 30 text_prev_apply_prob: 0.5 # 50% 概率注入前文 prompt lang_apply_prob: 0.5 # 50% 概率注入语种 token nolang_symbol: nolang frontend_conf: n_fft: 512 win_length: 400 hop_length: 160 # 10 ms 帧移16kHz 下即每帧 160 样本speech_length: 30正是 README 反复强调的“固定 30 秒”约束的出处——模型在 30 秒窗口上训练推理短音频时须补齐 30 秒长音频则靠decode_long的滑动缓冲处理。主干网络与多任务 CTC 的核心encoder: e_branchformer_ctc encoder_conf: output_size: 1024 # 即文件名中的 size1024 attention_heads: 16 num_blocks: 27 # ebf2727 个 Branchformer 块 input_layer: conv2d8 # 8 层卷积下采样前端 interctc_layer_idx: [6, 12, 15, 21] # 层级hierarchical中间 CTC interctc_use_conditioning: true use_cross_attention: [0, 0, 1, 0, 0, 1, ...] # 每 3 块中 1 块带 cross-attn use_flash_attn: true promptencoder: transformer promptencoder_conf: output_size: 512 num_blocks: 4 use_flash_attn: true model: espnet_ctc model_conf: interctc_weight: 0.8 sym_na: na ctc_asr_only: [true, true, true, false, false]从源码结构看这些配置分别映射到e_branchformer_ctc注册在 espnet2/tasks/s2t_ctc.py对应 EBranchformerCTCEncoder即在 Branchformer 之上为自条件机制加了 cross-attention 分支model: espnet_ctc对应 ESPnetS2TCTCModel类 docstring 直接注明 “OWSM-CTC model”。该模型持有encoder、prompt_encoder、ctc三件套前文 prompt 文本经 embedding 4 块 Transformer prompt encoder 编码再通过 cross-attention 注入主干语种/任务 token 经embed_proj投影后注入 encoder这正是zhoasr前缀在推理时通过lang_sym/task_sym生效的底层通道interctc_layer_idx: [6, 12, 15, 21]实现“层级多任务自条件 CTC”在 4 个中间层各挂一个 CTC 分支做辅助监督interctc_weight: 0.8控制其权重espnet_ctc_model.py 中assert 0.0 interctc_weight 1.0ctc_asr_only的五个布尔值按顺序对应“3 个 interctc 分支 最终 CTC 一个保留位”前三项为true表示中间 CTC 只用text.ctc纯 ASR 参考做监督与第 2 节text.ctc的设计一一对应use_cross_attention列表长度必须等于num_blocks27控制哪些块启用 cross-attention 读入 prompt。训练超参optim: adamw # lr2e-4, betas(0.9, 0.98), eps1e-6 scheduler: piecewiselinearwarmuplr scheduler_conf: warmup_steps_list: [0, 30000, 60000] warmup_lr_list: [0., 5.0e-05, 2.0e-04] batch_type: unsorted # batch_size: 256 帧注释4 samples/GPU num_iters_per_epoch: 15000 max_epoch: 45 best_model_criterion: # 以 valid cer_ctc / loss_ctc 选优 keep_nbest_models: 5 nbest_averaging_interval: 5 # 每 5 epoch 做一次 n-best 平均 use_amp: true seed: 2024此外 SpecAug 配置为 2 条宽度 0–27 的频率掩码 10 条宽度比例 0–0.05 的时间掩码、不做时间扭曲属于大规模语料上的温和正则化。4. 预训练模型获取README 给出两个 Hugging Face 模型espnet/owsm_ctc_v3.1_1B本 recipe 用上述配置从零训练的原始模型espnet/owsm_ctc_v3.2_ft_1Bv3.2 继续微调fine-tune版本。模型下载可走 ESPnet 的Speech2Text.from_pretrained(espnet/...)如第 5 节示例或用espnet-model-zoo的ModelDownloader见第 6 节强制对齐示例。5. 推理实战三种调用方式5.1 长音频批量推理Speech2Text.decode_longSpeech2Text.decode_long实现见 espnet2/bin/s2t_inference.py#L1222解码任意单条录音采用 CTC best-path 解码。源码文档字符串与 README 描述一致短于 30 秒的音频被补齐到 30 秒更长的切成重叠缓冲逐块解码。CTC-only 模型没有时间戳输出因此返回单个(start_time, end_time, text)元组覆盖整条录音对应源码中return [(0.0, len(speech) / self.sample_rate, text)]这一分支。from espnet2.bin.s2t_inference import Speech2Text s2t Speech2Text.from_pretrained( espnet/owsm_ctc_v3.1_1B, devicecuda, use_flash_attnFalse, # flash attn 已安装且 dtype 为 float16/bfloat16 时设为 True 更高效 lang_symeng, task_symasr, ) segments s2t.decode_long( audio.wav, # 单条音频输入路径或 1-D array/tensor batch_size16, context_len_in_secs4, ) text .join(segment for _, _, segment in segments) # 多条录音逐条调用 texts [ .join(t for _, _, t in s2t.decode_long(path, batch_size16)) for path in [audio1.wav, audio2.wav, audio3.wav] ]参数说明batch_size为并行解码的缓冲块数受显存约束context_len_in_secs是每个缓冲块两侧“解码后丢弃”的左右上下文秒数用来消除块边界效应源码签名中 CTC 路径只使用batch_size、context_len_in_secs、lang_sym、task_symcondition_on_prev_text、init_text等参数走 encoder-decoder 路径CTC-only checkpoint 不生效。另外README 指出旧的Speech2TextGreedySearch.batch_decode仍然可用但会触发DeprecationWarning新项目建议直接用Speech2Text。5.2 短音频 ASR/ST/LIDbest_path模型在 16kHz、固定 30 秒时长上训练。使用预训练模型时必须保证输入为 16kHz 且 pad/截断到 30 秒import librosa from espnet2.bin.s2t_inference import Speech2Text s2t Speech2Text.from_pretrained( espnet/owsm_ctc_v3.1_1B, devicecuda, generate_interctc_outputsFalse, lang_symeng, task_symasr, ) # 注意OWSM-CTC 在 16kHz、固定 30s 上训练。请确保输入采样率正确否则先重采样到 16k speech, rate librosa.load(xxx.wav, sr16000) speech librosa.util.fix_length(speech, size(16000 * 30)) # best_path 是 CTC best-path贪心解码一次 encoder 前向无搜索 # 若调用 s2t(speech) 则走 CTC prefix beam search慢得多且需要 beam_size、lm_weight 等参数 res s2t.best_path(speech)[0] print(res)这里best_path与s2t(speech)的区别是性能关键点前者直接取 CTC 网格的 Viterbi 最优路径一次前向出结果后者运行 prefix beam search虽然可以接beam_size、lm_weight等参数但对 CTC-only 模型通常没有收益README 明确建议用best_path。lang_sym/task_sym两个参数在 conf/decode_s2t.yaml 中也有对应默认值lang_sym: eng、task_sym: asr且beam_size: 1、lm_weight: 0.0做 ST 时可改为如lang_symeng, task_symst_zho指定“英→中”方向。5.3 长音频 ASR/ST 完整脚本import soundfile as sf import torch from espnet2.bin.s2t_inference import Speech2Text context_len_in_secs 4 # 缓冲推理的左右上下文 batch_size 32 # 视显存而定 s2t Speech2Text.from_pretrained( espnet/owsm_ctc_v3.1_1B, devicecuda if torch.cuda.is_available() else cpu, generate_interctc_outputsFalse, lang_symeng, task_symasr, ) speech, rate sf.read(xxx.wav) segments s2t.decode_long( speech, batch_sizebatch_size, context_len_in_secscontext_len_in_secs, ) print( .join(text for _, _, text in segments))与 5.1 的区别在于音频在 Python 侧用soundfile读入数组直接传入decode_long其read_audio会统一处理 path/array/tensor 三种输入并显式关闭 interctc 输出推理不需要中间 CTC 分支的张量。6. CTC 强制对齐CTCSegmentationCTC 模型的另一个直接红利是高效强制对齐——给定参考文本ctc-segmentation可以对任意长度音频做 token 级时间戳估计import soundfile as sf from espnet2.bin.s2t_align import CTCSegmentation from espnet_model_zoo.downloader import ModelDownloader # 先下载模型 d ModelDownloader() downloaded d.download_and_unpack(espnet/owsm_ctc_v3.2_ft_1B) # 或 espnet/owsm_ctc_v3.1_1B aligner CTCSegmentation( **downloaded, fs16000, ngpu1, batch_size32, # 批量并行解码显存小则调低 kaldi_style_textTrue, time_stampsauto, # token 下标 → 时间戳换算时 auto 比 fixed 更准 lang_symeng, task_symasr, context_len_in_secs2, # 缓冲解码的左右上下文 ) speech, rate sf.read(./test_utils/ctc_align_test.wav) print(fspeech duration: {len(speech) / rate : .2f} seconds) text utt1 THE SALE OF THE HOTELS utt2 IS PART OF HOLIDAYS STRATEGY utt3 TO SELL OFF ASSETS utt4 AND CONCENTRATE ON PROPERTY MANAGEMENT segments aligner(speech, text) print(segments)要点输入文本为 Kaldi 风格utt_id text多行格式kaldi_style_textTrue仓库自带测试音频 test_utils/ctc_align_test.wav 可直接复现time_stampsauto表示按 CTC 对齐路径的实际帧位置换算时间戳而非按 token 均分精度更高该实现基于 s2t_inference.py 中的缓冲解码逻辑decode_long_batched_buffered同样受batch_size与context_len_in_secs控制并行度与边界平滑。7. 总结与适用边界OWSM-CTC v3.1 recipe 提供了一条完整的 encoder-only 多任务语音基础模型链路数据层用text/text.ctc/text.prev三文件分别承载多任务目标、CTC 监督与自条件 prompt训练层由s2t_ctc预处理器30 秒定长窗口e_branchformer_ctc主干27 块、size 1024、4 个层级 interctc、cross-attention 注入 promptespnet_ctc模型封装组成参考配置在 64 卡 A100 上约 300 小时推理层则覆盖best_path≤30 秒短音频、decode_long任意长音频重叠缓冲与CTCSegmentation任意长音频强制对齐三个场景。使用时需牢记两条前提输入必须是 16kHz30 秒是模型的训练窗口长度短音频补齐、长音频切块均由Speech2Text自动完成跨块边界质量由context_len_in_secs控制。赞分享人工智能语音音频深度学习NLP【免费下载链接】espnetEnd-to-End Speech Processing Toolkit项目地址https://gitcode.com/gh_mirrors/es/espnet点击查看免费下载相关推荐SpeechBrain 实战使用 GigaSpeech 数据集训练 CTC 与 Transducer 语音识别模型SpeechBrain 实战使用 GigaSpeech 数据集训练 CTC 与 Transducer 语音识别模型 本指南基于 SpeechBrain 仓库中人工智能深度学习语音音频NLP预训练ESPnet 实战指南多 GPU 训练、run.sh 阶段控制与 CTC/Attention 解码模式切换ESPnet 实战指南多 GPU 训练、run.sh 阶段控制与 CTC/Attention 解码模式切换 本篇技术指南以 ESPnet 官方文档 doc/t人工智能语音音频深度学习NLPMXNet CTC-Loss 实战指南基于 LSTM 的验证码 OCR 训练与推理example/ctcMXNet CTC Loss 实战指南基于 LSTM 的验证码 OCR 训练与推理example/ctc 导读 本文围绕 MXNet 仓库 example深度学习机器学习人工智能上一篇Vue-example-login实战教程Vuex状态管理在登录流程中的最佳实践下一篇FrankenPHP 热重载Hot Reload实战指南从 Caddyfile 配置到浏览器实时更新创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关推荐

jetson-inference 深度学习入门:从训练到 TensorRT 推理的完整工作流
jetson-inference 深度学习入门:从训练到 TensorRT 推理的完整工作流

人工智能计算机视觉深度学习微调 【免费下载链接】jetson-inference Hello AI World guide to deploying deep-learning inference networks and deep vision primitives with TensorRT and NVIDIA Jetson. 项目地址: https://gitcode.com/gh_mirrors/je/jetson-inf… · 2026/9/25 7:19:26

Astron Agent 配置与认证 FAQ:Casdoor 登录循环、HTTPS 与注册开关等疑难问题全解
Astron Agent 配置与认证 FAQ:Casdoor 登录循环、HTTPS 与注册开关等疑难问题全解

人工智能AI AgentAgent 编排RPA后端前端企业应用 【免费下载链接】astron-agent Enterprise-grade, commercial-friendly agentic workflow platform for building next-generation SuperAgents. 项目地址: https://gitcode.com/gh_mirrors/as/astron-agent 点击查看… · 2026/9/25 7:19:26

VoltAgent Trace Logs 实战指南:利用结构化日志快速定位 Agent 运行错误与元数据
VoltAgent Trace Logs 实战指南:利用结构化日志快速定位 Agent 运行错误与元数据

人工智能AI AgentAgent 框架后端多智能体RAG工具调用Agent 记忆 【免费下载链接】voltagent AI Agent Engineering Platform built on an Open Source TypeScript AI Agent Framework 项目地址: https://gitcode.com/gh_mirrors/vo/voltagent 点击查看 免费下载 Tr… · 2026/9/25 7:19:26

新手避坑指南:AI博士周有贵教你,选GEO软件拒绝套路只讲干货
新手避坑指南:AI博士周有贵教你,选GEO软件拒绝套路只讲干货

很多做网站获客、搜索运营的新手,刚接触 GEO 生成式搜索引擎优化的时候,很容易被各种宣传话术绕晕。市面上相关工具、服务商参差不齐,不少运营新人踩坑:工具功能虚标、关键词挖掘不准、收费暗藏套路,做出来的内容不匹配… · 2026/9/25 7:52:19

使用 AWS SDK for Java 2.x 管理 AWS Lambda 函数:完整场景实战指南
使用 AWS SDK for Java 2.x 管理 AWS Lambda 函数:完整场景实战指南

示例工程教程后端 【免费下载链接】aws-doc-sdk-examples Welcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below. 项目地… · 2026/9/25 7:51:16

Apache Pulsar 模块化负载管理器(Modular Load Manager):启用方法、验证手段与源码级实现解析
Apache Pulsar 模块化负载管理器(Modular Load Manager):启用方法、验证手段与源码级实现解析

消息队列后端流处理 【免费下载链接】pulsar Apache Pulsar - distributed pub-sub messaging system 项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar 点击查看 免费下载 在 Pulsar 集群中,命名空间 bundle 如何分配到哪个 broker&#xff… · 2026/9/25 7:51:16

安卓逆向助手:抓包脱壳反编译全流程脚本化实战
安卓逆向助手:抓包脱壳反编译全流程脚本化实战

简介:安卓逆向助手是一款面向Android应用开发者与安全研究人员的图形化逆向工具,旨在降低APK反编译与分析门槛,让初学者也能快速理解应用内部结构。它集成dex2jar、JD-GUI、apktool、baksmali等常用组件,支持一键将Dalvik字节码转… · 2026/9/25 7:50:58

通信驱动的CRM工作台:DeskcommCRM设计思路与落地实践
通信驱动的CRM工作台:DeskcommCRM设计思路与落地实践

最近大半年我在推进一个项目,内部代号 DeskcommCRM,聊的人不多,但用起来确实和传统 CRM 是两个思路。它不是那种把客户信息塞进数据库就完事的系统,而是把“客户关系”这件事重新拉回到桌面上——电话、邮件、会话、跟进记录&… · 2026/9/25 7:50:45

SPL 迁移到 Axiom APL 实战指南:基于 spl-to-apl 技能的完整查询翻译手册
SPL 迁移到 Axiom APL 实战指南:基于 spl-to-apl 技能的完整查询翻译手册

后端前端AI 技能AI 插件搜索引擎 【免费下载链接】clawhub Skill Plugin Registry for OpenClaw 项目地址: https://gitcode.com/gh_mirrors/mo/clawhub 点击查看 免费下载 本指南围绕本仓库 .agents/skills/spl-to-apl/ 目录下的 SPL→APL 翻译技能展开&#xff… · 2026/9/25 7:50:39

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码