CANN 组织链接 : https://atomgit.com/cann
atvoss 仓库链接 : https://atomgit.com/cann/atvoss
在数字化时代,智能语音和多媒体处理技术已成为人机交互和信息感知不可或缺的核心。从智能手机的语音助手到自动驾驶的声学环境感知,从短视频平台的实时特效到云端媒体内容的智能审核,这些应用都对底层硬件和软件框架提出了严苛的实时性、高并发和高吞吐量要求。面对海量、复杂的音视频数据流,传统处理方式已难以满足需求,迫切需要专用加速器(如 AI 处理器)的强大算力支撑。
atvoss 仓库正是 CANN 软件栈在智能语音与多媒体领域的核心贡献。它提供了一套全面、高效、专为 AI 处理器优化的多媒体处理框架和算子库。atvoss 不仅封装了从媒体编解码、预处理到特征提取等一系列核心功能,更重要的是,它将这些功能深度融合到 CANN 编译与运行时系统,确保音视频数据能够在 AI 处理器上以极致效率流动和计算。通过 atvoss,开发者能够轻松构建高性能、低延迟的智能语音和多媒体应用,从而加速语音识别、语音合成、视频分析等前沿 AI 技术在各行各业的落地。本文将深入探讨 atvoss 的技术内涵、其在 AI 处理器生态中的价值以及如何赋能新一代智能交互应用。
1. 引言:智能语音与多媒体处理的挑战
智能语音与多媒体处理作为 AI 领域的重要分支,其快速发展伴随着严峻的计算挑战。
1.1 智能语音与多媒体处理的爆发式增长
随着智能设备的普及和 AI 技术的成熟,语音和多媒体应用需求呈现指数级增长:
- 语音交互的普及:智能音箱、智能车载系统、手机语音助手等,使得语音识别(ASR)和语音合成(TTS)成为主流交互方式。
- 富媒体内容的爆炸:短视频、直播、在线教育等催生了对视频编解码、内容理解、实时处理的巨大需求。
- AI 深度融合:语音识别、人脸识别、行为分析等 AI 模型被广泛应用于安防、金融、医疗等领域,对前端数据处理和后端模型推理的性能提出更高要求。
1.2 实时性与高并发的严苛要求
多数智能语音与多媒体应用都对延迟和并发能力有着极高的要求:
- 实时交互体验:语音助手需要毫秒级的响应速度,视频会议需要端到端的低延迟,以确保流畅自然的用户体验。
- 高并发服务:在云端,数百万用户同时发起的语音请求或视频流分析任务,需要系统具备强大的并发处理能力。
- 边缘端低功耗:在边缘设备(如智能摄像头、IoT 设备)上,需要在有限的计算资源和功耗预算下,实现高效的实时处理。
1.3 AI 处理器在多媒体领域的优势与 atvoss 的定位
AI 处理器为解决这些挑战提供了理想的硬件基础:
- 专用加速能力:AI 处理器内置的硬件单元(如视频硬解码器、张量计算单元)能够高效处理编解码、信号处理和深度学习模型推理。
- 高吞吐量:针对并行计算设计的架构,使得 AI 处理器能够同时处理多路音视频流或加速复杂的媒体处理任务。
atvoss的核心使命 :atvoss正是为了充分释放 AI 处理器在智能语音和多媒体处理领域的潜力而生,它提供了一套高度优化、面向硬件的软件解决方案,连接上层应用与底层硬件,构建高性能的音视频处理管道。
2. atvoss 核心:面向 AI 处理器的多媒体处理框架
atvoss 提供了一套统一、高效的多媒体处理框架,抽象了底层硬件复杂性,为开发者提供了便捷的接口。
2.1 统一的多媒体处理抽象层
atvoss 的设计目标之一是提供一个通用的抽象层,屏蔽底层硬件和操作系统差异:
- 标准化 API:提供一套一致的、易于使用的 C++ 或 Python API,用于多媒体数据的输入、处理和输出。
- 硬件解耦 :开发者无需关心具体的 AI 处理器型号或底层硬件接口,
atvoss会自动将任务调度到最优的硬件资源上。 - 跨平台兼容性 :确保
atvoss及其组件在不同的 AI 处理器部署环境中(如云、边、端)都能保持一致的行为和性能。
2.2 模块化设计与可扩展性
atvoss 采用模块化设计,方便开发者灵活组合功能和扩展:
- 组件化架构:框架被划分为多个独立的功能模块,例如媒体源管理、编解码器、滤波器、特征提取器等,每个模块都可以单独配置和使用。
- 灵活的管道构建:开发者可以通过简单的配置或编程接口,将这些模块串联起来,构建定制化的音视频处理管道。
- 易于集成新功能:开放的架构允许开发者轻松地集成新的编解码器、信号处理算法或自定义算子,以满足不断变化的应用需求。
2.3 主要功能组件概览
atvoss 框架内部包含了一系列关键功能组件,支撑其多媒体处理能力:
- 媒体数据输入/输出模块:负责从文件、网络流或传感器获取音视频数据,并将处理结果输出到指定目标。
- 音视频编解码器 (Codec):支持主流的音视频编码标准,如 H.264/H.265 (视频)、AAC/MP3 (音频),利用 AI 处理器内置的硬解码器实现高性能编解码。
- 预处理与后处理模块 :
- 音频:降噪、回声消除、增益控制、语音活动检测 (VAD) 等。
- 视频:去噪、去畸变、图像缩放、裁剪、颜色空间转换 (如 YUV <-> RGB) 等。
- 特征提取模块 :
- 音频:MFCC (梅尔频率倒谱系数)、FBank (梅尔滤波器组特征)、声谱图等,为语音 AI 模型提供输入。
- 视频:用于图像识别、目标检测的前端特征生成。
3. 算子优化:音视频处理的加速引擎
atvoss 的核心优势在于其高度优化的音视频处理算子,它们直接在 AI 处理器上运行,实现性能飞跃。
3.1 专用音视频处理算子库
atvoss 提供了一系列专为 AI 处理器定制的音视频处理算子:
- 音频信号处理算子 :
- FFT/iFFT (快速傅里叶变换及其逆变换):高效的频域分析和合成,是声学特征提取的基础。
- Mel-filterbank:将线性频谱映射到梅尔尺度,模拟人耳听觉特性,用于生成 FBank 特征。
- MFCC (梅尔频率倒谱系数):最常用的语音特征之一,通过 DCT 变换进一步压缩 FBank 特征。
- VAD (语音活动检测):实时识别语音段落,过滤背景噪声,减少后续 AI 模型的计算量。
- 视频图像处理算子 :
- 图像缩放与裁剪:用于调整图像尺寸以适应不同模型输入或显示需求,支持高质量插值算法。
- 颜色空间转换:例如 YUV 到 RGB 的转换,是视频流处理中常见的操作。
- 去噪与增强:利用 AI 处理器并行能力实现实时的图像质量优化。
3.2 深度融合与硬件加速
atvoss 算子通过深度融合和硬件利用,实现计算效率最大化:
- 异构硬件利用:将编解码任务映射到 AI 处理器内置的硬件编解码器,将信号处理算子映射到 AI 处理器的高速计算单元(如向量计算单元)。
- 算子融合:将多个连续的、数据依赖强的音视频处理步骤融合成一个单一的 Kernel,例如"FFT + Mel-filterbank + Log",减少中间数据写回内存的开销。
- 片上缓存优化:优化数据传输路径,确保中间处理结果尽可能保留在 AI 处理器的高速片上缓存中,降低对全局显存带宽的依赖。
3.3 并行计算与流式处理能力
atvoss 充分利用 AI 处理器的大规模并行计算能力,实现高效的流式处理:
- 数据并行 :对于多路音视频流,
atvoss可以在 AI 处理器上并行处理,实现高并发吞吐量。 - 任务并行:在一个音视频处理管道中,不同的处理阶段(如解码、预处理、特征提取)可以以流水线方式并行执行。
- 异步调度 :
atvoss利用 AI 处理器提供的异步任务调度机制,将计算和数据传输分离,隐藏延迟。
4. 集成与协同:融入 CANN 生态,无缝部署
atvoss 并非孤立的存在,它与 CANN 软件栈的核心组件紧密集成,确保了其在整个 AI 处理器生态中的高效运行和无缝部署。
4.1 与 CANN ge 计算图引擎的深度融合
atvoss 的处理流程能够被 CANN 的计算图引擎 ge 识别并优化:
- 图表示与优化 :
atvoss中构建的音视频处理管道可以被ge表示为计算图。ge对这些图进行全局分析,应用算子融合、内存优化、并行调度等策略,生成高效的执行计划。 - 优化算子的调度 :
atvoss提供的专用优化算子被ge识别并优先调度到 AI 处理器上执行,取代传统通用实现,从而确保性能优势。 - 端到端性能 :通过
ge,atvoss实现了从前端媒体数据输入到后端 AI 模型推理的整个流程的端到端优化,消除了潜在的性能瓶颈。
4.2 与 metadef 算子元数据定义的协同
atvoss 中所有算子的正确性与兼容性,都得益于 metadef 的元数据规范:
- 算子原型规范 :
atvoss中的每个音视频处理算子,如 FFT、MelFilterbank、ColorConvert 等,都严格遵循metadef定义的算子原型,包括其输入输出张量、数据类型、形状和格式。 - 形状与类型推导 :
atvoss的算子提供了精确的形状和数据类型推导函数。这些函数在编译时被ge调用,以确保计算图中各张量属性的正确性,并辅助进行内存分配和优化。 - 统一接口 :通过
metadef,atvoss的算子能够与 CANN 生态中的其他 AI 算子无缝衔接,共同构建复杂的 AI 任务。
4.3 支持多场景部署与弹性扩展
atvoss 的设计考虑了不同部署环境的需求,提供了灵活的部署能力:
- 云端高性能处理 :在数据中心,
atvoss能够驱动 AI 处理器集群,实现海量音视频内容的并行处理和分析,满足高吞吐量需求。 - 边缘设备实时推理 :针对资源受限的边缘设备,
atvoss优化了内存占用和计算效率,使得智能摄像头、智能音箱等设备能够进行实时的本地音视频处理。 - 端侧低功耗运行 :通过与
ge的进一步优化,atvoss能够生成极致轻量化、低功耗的代码,适用于手机、可穿戴设备等端侧应用。
5. 应用场景:赋能智能语音与多媒体创新
atvoss 的强大功能使其成为智能语音和多媒体领域创新应用开发的有力支撑。
5.1 语音识别与智能助手
atvoss 为语音识别(ASR)系统提供高效的前端处理能力,显著提升整体性能:
- 高质量语音特征提取:快速准确地提取 MFCC、FBank 等声学特征,为 ASR 模型提供高质量输入,提高识别准确率。
- 实时语音活动检测 (VAD):过滤掉非语音片段,减少 ASR 模型的无效计算,降低延迟,节省计算资源。
- 噪声抑制与语音增强:在复杂环境中提供高质量的语音输入,即使在嘈杂环境下也能确保语音助手的良好用户体验。
5.2 语音合成(TTS)与声纹识别
在语音生成和生物识别领域,atvoss 同样发挥关键作用:
- 高效音频生成与处理 :在 TTS 系统中,
atvoss能够快速处理合成的原始音频信号,进行音色调整、韵律优化等,保障合成语音的自然流畅。 - 声纹特征提取:为声纹识别模型提供优化的声学特征,支持身份验证和说话人识别等应用。
- 多语种支持:通过灵活的配置和算子组合,支持不同语种的语音合成与识别需求。
5.3 音视频内容分析与智能驾驶
atvoss 在复杂的多媒体内容分析中展现出强大能力:
- 视频内容理解:高效的视频解码和图像预处理,为行为识别、目标检测、人脸识别等 AI 模型提供标准化的输入。
- 音频事件检测:识别环境音中的特定事件(如警报声、婴儿哭声),应用于安防监控或智能家居。
- 智能驾驶 :在车载系统中,
atvoss处理来自麦克风阵列的语音指令和声学环境信息,以及来自摄像头的视觉数据,为驾驶辅助和人车交互提供实时感知。
5.4 媒体编解码与流媒体优化
在媒体内容的传输、存储和处理链条中,atvoss 优化了关键环节:
- 高性能编解码:利用 AI 处理器硬解码能力,实现多路高清视频流的实时解码和转码,满足云端媒体处理需求。
- 媒体流预处理:对媒体流进行实时的去噪、增强、格式转换等操作,优化传输效率和最终呈现质量。
- 降低成本:通过硬件加速和软件优化,显著降低了媒体处理的计算资源消耗和运营成本。
6. 未来展望:持续演进,应对新兴挑战
atvoss 作为 CANN 软件栈在多媒体领域的关键组件,将持续演进,以应对不断变化的技术和应用需求。
6.1 支持新的媒体格式与编码标准
随着多媒体技术的发展,新的媒体格式和编码标准层出不穷:
- 更新编解码器 :
atvoss将持续集成对最新视频编码标准(如 AV1、VVC)和音频编码标准的支持,确保其在媒体处理领域的领先性。 - 高动态范围 (HDR) 与高帧率 (HFR):优化对 HDR 和 HFR 视频流的处理能力,满足电影制作、游戏和专业视频应用的需求。
- 空间音频:探索对多声道、沉浸式空间音频格式的处理支持,提升用户体验。
6.2 更深度的 AI 融合与智能化处理
未来的 atvoss 将更紧密地与深度学习模型结合,实现更智能的媒体处理:
- 基于深度学习的信号处理:将传统的信号处理算法与深度学习技术融合,例如利用神经网络进行更精细的语音降噪、盲源分离、超分辨率视频重建等。
- 自适应媒体处理 :
atvoss将探索根据内容类型、网络环境和用户偏好,智能地调整媒体处理管道和优化参数,实现自适应媒体体验。 - 端到端优化:将媒体处理与 AI 模型推理更紧密地耦合,实现从原始感知数据到高级语义理解的端到端统一优化。
6.3 端边云协同优化与隐私保护
随着应用场景的扩展,atvoss 将聚焦于提供更全面的解决方案:
- 统一管理与调度:为端、边、云等多层次异构计算环境提供统一的媒体处理任务管理和资源调度能力,实现无缝协同。
- 低功耗与实时性极致优化:持续在算子设计、内存管理和调度策略上进行优化,以满足对功耗和实时性最为严苛的边缘和端侧场景。
- 隐私计算与联邦学习 :探索如何在保护用户隐私的前提下,在
atvoss中集成隐私计算技术,支持对敏感音视频数据的处理和分析。
附录:atvoss 概念性 C++ 音频特征提取管道示例
以下是一个概念性的 C++ 代码片段,旨在说明 atvoss 仓库中,如何通过其提供的 API 构建一个简单的音频特征提取管道(例如:从原始音频数据到梅尔滤波器组特征 FBank)。此示例着重于展示 API 的调用模式和核心概念,它并非直接可编译运行的代码 ,因为它省略了所有必要的头文件定义、完整的错误处理、以及具体的内部 Kernel 实现细节。其目的仅仅是展示如何通过 atvoss 抽象地将复杂的音频处理流程封装成可在 AI 处理器上运行的组件。
cpp
#include <iostream>
#include <vector>
#include <string>
#include <memory> // For std::unique_ptr
#include <map>
#include <functional>
#include <chrono> // For std::this_thread::sleep_for
#include <thread> // For std::this_thread::sleep_for
#include <numeric> // For std::iota
// 概念性:张量描述,与 CANN 核心张量概念类似
struct AtvossTensorDesc {
std::string name;
std::vector<long> dims; // 张量维度
std::string dtype; // 数据类型,如 "float32", "int16"
void* device_ptr = nullptr; // AI 处理器上的数据指针
size_t GetSizeBytes() const {
size_t size = 1;
for (long dim : dims) {
size *= dim;
}
if (dtype == "float32") return size * 4;
if (dtype == "int16") return size * 2;
return size; // 默认1字节
}
};
// 概念性:AI 处理器设备和内存管理接口 (通常由 CANN Runtime 提供)
namespace AiProcessorRuntime {
void* MallocDeviceMemory(size_t size_bytes) {
std::cout << "[AiProcessorRuntime] 在设备上分配 " << size_bytes << " 字节内存..." << std::endl;
void* ptr = reinterpret_cast<void*>(0x40000000ULL + (rand() % 0x100000ULL)); // 概念性地址
std::this_thread::sleep_for(std::chrono::milliseconds(1));
return ptr;
}
void FreeDeviceMemory(void* dev_ptr) {
if (dev_ptr) {
std::cout << "[AiProcessorRuntime] 释放设备内存 " << dev_ptr << "..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
void MemcpyHostToDevice(void* dev_ptr, const void* host_ptr, size_t size_bytes) {
std::cout << "[AiProcessorRuntime] 拷贝 " << size_bytes << " 字节从 Host " << host_ptr << " 到 Device " << dev_ptr << "..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
void MemcpyDeviceToHost(void* host_ptr, const void* dev_ptr, size_t size_bytes) {
std::cout << "[AiProcessorRuntime] 拷贝 " << size_bytes << " 字节从 Device " << dev_ptr << " 到 Host " << host_ptr << "..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
// 概念性:AI 处理器上的 Stream 对象,用于异步执行
class Stream {
public:
Stream() { std::cout << "[AiProcessorRuntime.Stream] 创建异步流." << std::endl; }
void Synchronize() {
std::cout << "[AiProcessorRuntime.Stream] 同步异步流,等待所有任务完成." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
~Stream() { std::cout << "[AiProcessorRuntime.Stream] 销毁异步流." << std::endl; }
};
} // namespace AiProcessorRuntime
// 概念性:atvoss 库中的音频处理算子接口
namespace atvoss {
// 概念性:音频帧预处理算子,例如分帧、加窗
void LaunchFramePreprocessKernel(
const AtvossTensorDesc& raw_audio_input, // 原始音频数据
const AtvossTensorDesc& frame_output, // 分帧后的数据
int sample_rate,
int frame_len,
int frame_shift,
AiProcessorRuntime::Stream& stream
) {
std::cout << "[atvoss] 启动 Frame Preprocess Kernel..." << std::endl;
// 实际 Kernel 会在 AI 处理器上进行分帧、加窗操作
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
// 概念性:FFT 算子
void LaunchFFTKernel(
const AtvossTensorDesc& frame_input, // 分帧后的数据
const AtvossTensorDesc& fft_output, // FFT 结果 (频谱)
AiProcessorRuntime::Stream& stream
) {
std::cout << "[atvoss] 启动 FFT Kernel..." << std::endl;
// 实际 Kernel 会在 AI 处理器上进行 FFT 变换
std::this_thread::sleep_for(std::chrono::milliseconds(15));
}
// 概念性:梅尔滤波器组算子
void LaunchMelFilterbankKernel(
const AtvossTensorDesc& fft_input, // FFT 结果
const AtvossTensorDesc& fbank_output, // FBank 特征
int num_mel_bins,
int sample_rate,
float min_freq,
float max_freq,
AiProcessorRuntime::Stream& stream
) {
std::cout << "[atvoss] 启动 Mel Filterbank Kernel..." << std::endl;
// 实际 Kernel 会在 AI 处理器上应用梅尔滤波器组
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
// 概念性:对数能量/log-mel 算子 (通常与 MelFilterbank 融合)
void LaunchLogMelKernel(
const AtvossTensorDesc& mel_input, // Mel 能量
const AtvossTensorDesc& log_mel_output, // Log-Mel 特征
AiProcessorRuntime::Stream& stream
) {
std::cout << "[atvoss] 启动 Log-Mel Kernel..." << std::endl;
// 实际 Kernel 会在 AI 处理器上进行取对数操作
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
// 概念性:一个封装了整个 FBank 提取流程的处理器类
class AudioFeatureProcessor {
public:
AudioFeatureProcessor(int sample_rate, int frame_len_ms, int frame_shift_ms, int num_mel_bins)
: sample_rate_(sample_rate), frame_len_ms_(frame_len_ms), frame_shift_ms_(frame_shift_ms), num_mel_bins_(num_mel_bins) {
std::cout << "[atvoss.AudioFeatureProcessor] 初始化音频特征处理器." << std::endl;
// 更多初始化逻辑,如加载预计算的滤波器组矩阵等
}
// 处理一帧或一个批次的原始音频数据
AtvossTensorDesc ProcessAudioFrame(const AtvossTensorDesc& raw_audio_input) {
AiProcessorRuntime::Stream stream; // 为本次处理创建新流
// 1. 概念性:分帧和加窗
int frame_len_samples = sample_rate_ * frame_len_ms_ / 1000;
int frame_shift_samples = sample_rate_ * frame_shift_ms_ / 1000;
long num_frames = (raw_audio_input.dims[0] - frame_len_samples) / frame_shift_samples + 1;
AtvossTensorDesc frame_output_desc = {"frames", {num_frames, (long)frame_len_samples}, "float32"};
frame_output_desc.device_ptr = AiProcessorRuntime::MallocDeviceMemory(frame_output_desc.GetSizeBytes());
LaunchFramePreprocessKernel(raw_audio_input, frame_output_desc, sample_rate_, frame_len_samples, frame_shift_samples, stream);
// 2. 概念性:FFT
AtvossTensorDesc fft_output_desc = {"fft_result", {num_frames, (long)(frame_len_samples / 2 + 1)}, "float32"};
fft_output_desc.device_ptr = AiProcessorRuntime::MallocDeviceMemory(fft_output_desc.GetSizeBytes());
LaunchFFTKernel(frame_output_desc, fft_output_desc, stream);
// 3. 概念性:梅尔滤波器组 + Log
AtvossTensorDesc fbank_output_desc = {"fbank_features", {num_frames, (long)num_mel_bins_}, "float32"};
fbank_output_desc.device_ptr = AiProcessorRuntime::MallocDeviceMemory(fbank_output_desc.GetSizeBytes());
// 实际可能是一个融合 Kernel: LaunchFusedMelLogFbankKernel
LaunchMelFilterbankKernel(fft_output_desc, fbank_output_desc, num_mel_bins_, sample_rate_, 0.0f, sample_rate_ / 2.0f, stream);
LaunchLogMelKernel(fbank_output_desc, fbank_output_desc, stream); // 这里直接对fbank_output_desc进行inplace操作以简化
// 同步流,确保所有计算完成
stream.Synchronize();
// 释放中间内存
AiProcessorRuntime::FreeDeviceMemory(frame_output_desc.device_ptr);
AiProcessorRuntime::FreeDeviceMemory(fft_output_desc.device_ptr);
return fbank_output_desc; // 返回 FBank 特征的描述
}
private:
int sample_rate_;
int frame_len_ms_;
int frame_shift_ms_;
int num_mel_bins_;
// 其他内部状态或预计算数据
};
} // namespace atvoss
int main() {
std::cout << "--- atvoss 概念性 C++ 音频特征提取管道示例 ---" << std::endl;
// 1. 初始化 atvoss 音频特征处理器
atvoss::AudioFeatureProcessor processor(
16000, // 采样率 16kHz
25, // 帧长 25ms
10, // 帧移 10ms
40 // 梅尔滤波器组数量 40
);
// 2. 准备概念性原始音频数据 (主机端)
// 假设 16kHz 采样率,1 秒音频数据
const int audio_duration_seconds = 1;
const int total_samples = 16000 * audio_duration_seconds;
std::vector<int16_t> host_raw_audio(total_samples);
std::iota(host_raw_audio.begin(), host_raw_audio.end(), 0); // 填充一些模拟数据
// 3. 在 AI 处理器上分配原始音频数据内存,并拷贝数据
AtvossTensorDesc raw_audio_input_desc = {"raw_audio", {(long)total_samples}, "int16"};
raw_audio_input_desc.device_ptr = AiProcessorRuntime::MallocDeviceMemory(raw_audio_input_desc.GetSizeBytes());
AiProcessorRuntime::MemcpyHostToDevice(raw_audio_input_desc.device_ptr, host_raw_audio.data(), raw_audio_input_desc.GetSizeBytes());
// 4. 调用处理器进行特征提取
std::cout << "\n--- 开始特征提取管道 ---" << std::endl;
AtvossTensorDesc fbank_features_desc = processor.ProcessAudioFrame(raw_audio_input_desc);
std::cout << "--- 特征提取管道完成 ---" << std::endl;
// 5. 打印输出特征的描述
std::cout << "\n提取到的 FBank 特征描述:" << std::endl;
std::cout << " - 名称: " << fbank_features_desc.name << std::endl;
std::cout << " - 维度: {";
for (long dim : fbank_features_desc.dims) {
std::cout << dim << " ";
}
std::cout << "}" << std::endl;
std::cout << " - 数据类型: " << fbank_features_desc.dtype << std::endl;
std::cout << " - 设备指针: " << fbank_features_desc.device_ptr << std::endl;
// 6. 将特征从 AI 处理器拷贝回主机 (如果需要进行后续处理或检查)
std::vector<float> host_fbank_features(fbank_features_desc.GetSizeBytes() / sizeof(float));
AiProcessorRuntime::MemcpyDeviceToHost(host_fbank_features.data(), fbank_features_desc.device_ptr, fbank_features_desc.GetSizeBytes());
std::cout << "\nFBank 特征部分数据 (前5个):" << std::endl;
for (int i = 0; i < std::min((int)host_fbank_features.size(), 5); ++i) {
std::cout << host_fbank_features[i] << " ";
}
std::cout << std::endl;
// 7. 清理设备内存
AiProcessorRuntime::FreeDeviceMemory(raw_audio_input_desc.device_ptr);
AiProcessorRuntime::FreeDeviceMemory(fbank_features_desc.device_ptr);
std::cout << "\n--- atvoss 概念性 API 演示结束 ---" << std::endl;
return 0;
}