最近研究一个C#小项目,接触到sherpa-onnx本地部署语音识别模型,想着用C#做本地调用,采用C#调python脚本的方式还要安装python环境,有时候不方便。网上没有找到直接用C#的详细教程,对小白不友好,只能自己摸索。该篇文章只是学习过程的一个记录。如果有错误欢迎指正,也欢迎各位大佬分享更好的C#本地方案。
1. sherpa-onnx下载安装:
查看官方文档Installation — sherpa 1.3 documentation
本次只用cpu版。
2. 命令行测试
查看C# API文档,本次使用Non-streaming的paraformer。
进入路径sherpa-onnx/dotnet-examples/offline-decode-files下载模型,如果命令行下载速度太慢可以手动在浏览器下载,将下载路径直接在浏览器打开即可:
下载完成后解压到文档要求的路径:
之后打开cmd在该目录下执行命令:
dotnet run -c Release \
--paraformer ./sherpa-onnx-paraformer-zh-2023-03-28/model.int8.onnx \
--tokens ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt \
--files ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav \
./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/1.wav \
./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/8k.wav
写在一行中:
dotnet run -c Release --paraformer ./sherpa-onnx-paraformer-zh-2023-03-28/model.int8.onnx --tokens ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt --files ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/0.wav ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/1.wav ./sherpa-onnx-paraformer-zh-2023-03-28/test_wavs/8k.wav
得到结果:
3. C#使用命令行的方式调用本地模型(用visual studio简单写个winform测试)
简单做个窗口:
编写主程序代码:
using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text;
namespace sherpaOnnx_test
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string base_dir = "./sherpa-onnx-paraformer-zh-2023-03-28/";
// 定义要执行的命令和参数
string command = $"dotnet run -c Release --paraformer {base_dir}model.int8.onnx " +
$"--tokens {base_dir}tokens.txt " +
$"--files {base_dir}test_wavs/0.wav ";
if (string.IsNullOrEmpty(command))
{
MessageBox.Show("请输入要执行的命令");
return;
}
try
{
// 配置进程启动参数
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = $"/c {command}", // /c 参数表示执行后关闭CMD窗口
RedirectStandardOutput = true, // 重定向标准输出
RedirectStandardError = true, // 重定向错误输出
UseShellExecute = false, // 不使用系统Shell执行
CreateNoWindow = true, // 不创建新窗口
WindowStyle = ProcessWindowStyle.Hidden,
StandardOutputEncoding = Encoding.UTF8, // 设置输出编码为UTF-8
StandardErrorEncoding = Encoding.UTF8 // 设置错误输出编码为UTF-8
};
// 创建进程对象
using (Process process = new Process())
{
process.StartInfo = startInfo;
// 启动进程
process.Start();
// 同步读取输出流(先读取后等待退出避免死锁)
string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd();
// 等待进程结束
process.WaitForExit();
// 显示结果
richTextBox1.Text = $"输出:\n{output}";
if (!string.IsNullOrEmpty(error))
{
richTextBox1.Text += $"\n错误:\n{error}";
}
}
}
catch (Exception ex)
{
MessageBox.Show($"执行命令时出错:{ex.Message}");
}
}
}
}
代码中的编码一定要设置,否则输出会有乱码。
但是该代码直接执行会报找不到文件的错,因为代码启动的命令行程序只会在项目的Debug目录下执行(因为这里有项目的执行文件.exe)。
所以要将下面sherpa-onnx的模型和代码文件放到项目的Debug文件夹下:
同时将Common复制到Debug同级目录下:
如此,运行程序,单机button得到测试结果(只测试了一个语音文件):
要识别的语音文件的路径可以在命令中修改
在上面的结果中发现有些输出并不需要,于是打开sherpa-onnx的Program.cs文件(现在在Debug文件夹内)
找到结果输出位置,将不必要的输出注释:
再次运行:
后续就可以做应用上的代码编写了。