Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for netstandard and net core in dotnet client #3373

Closed
wants to merge 47 commits into from

Conversation

stepkillah
Copy link
Collaborator

@stepkillah stepkillah commented Oct 13, 2020

Added additional targets for dotnet client to support netstandard2.0, netstandard2.1, netcoreapp3.1.

Not sure if something else required, probably need to update nuget, let me know if something missing or I need to add something more.

@community-tc-integration
Copy link

No Taskcluster jobs started for this pull request
The `allowPullRequests` configuration for this repository (in `.taskcluster.yml` on the
default branch) does not allow starting tasks for this pull request.

@stepkillah stepkillah changed the title Add support for netstandard and net core Add support for netstandard and net core in dotnet client Oct 13, 2020
@lissyx lissyx requested a review from carlfm01 October 13, 2020 08:28
Copy link
Collaborator

@lissyx lissyx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stepkillah Thanks, but we will also need CI support to handle building and testing that.

Could you have a look around

do_deepspeech_netframework_build()
{
cd ${DS_DSDIR}/native_client/dotnet
# Setup dependencies
nuget restore DeepSpeech.sln
MSBUILD="$(cygpath 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe')"
# We need MSYS2_ARG_CONV_EXCL='/' otherwise the '/' of CLI parameters gets mangled and disappears
# We build the .NET Client for .NET Framework v4.5,v4.6,v4.7
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechClient/DeepSpeechClient.csproj \
/p:Configuration=Release \
/p:Platform=x64 \
/p:TargetFramework="net452" \
/p:OutputPath=bin/nuget/x64/v4.5
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechClient/DeepSpeechClient.csproj \
/p:Configuration=Release \
/p:Platform=x64 \
/p:TargetFramework="net46" \
/p:OutputPath=bin/nuget/x64/v4.6
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechClient/DeepSpeechClient.csproj \
/p:Configuration=Release \
/p:Platform=x64 \
/p:TargetFramework="net47" \
/p:OutputPath=bin/nuget/x64/v4.7
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechClient/DeepSpeechClient.csproj \
/p:Configuration=Release \
/p:Platform=x64 \
/p:TargetFramework="uap10.0" \
/p:OutputPath=bin/nuget/x64/uap10.0
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechConsole/DeepSpeechConsole.csproj \
/p:Configuration=Release \
/p:Platform=x64
}
do_deepspeech_netframework_wpf_build()
{
cd ${DS_DSDIR}/native_client/dotnet
# Setup dependencies
nuget install DeepSpeechWPF/packages.config -OutputDirectory DeepSpeechWPF/packages/
MSBUILD="$(cygpath 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin\MSBuild.exe')"
# We need MSYS2_ARG_CONV_EXCL='/' otherwise the '/' of CLI parameters gets mangled and disappears
# Build WPF example
MSYS2_ARG_CONV_EXCL='/' "${MSBUILD}" \
DeepSpeechWPF/DeepSpeech.WPF.csproj \
/p:Configuration=Release \
/p:Platform=x64 \
/p:OutputPath=bin/x64
}
do_nuget_build()
{
PROJECT_NAME=$1
if [ -z "${PROJECT_NAME}" ]; then
exit "Please call with a valid PROJECT_NAME"
exit 1
fi;
cd ${DS_DSDIR}/native_client/dotnet
cp ${DS_TFDIR}/bazel-bin/native_client/libdeepspeech.so nupkg/build
# We copy the generated clients for .NET into the Nuget framework dirs
mkdir -p nupkg/lib/net45/
cp DeepSpeechClient/bin/nuget/x64/v4.5/DeepSpeechClient.dll nupkg/lib/net45/
mkdir -p nupkg/lib/net46/
cp DeepSpeechClient/bin/nuget/x64/v4.6/DeepSpeechClient.dll nupkg/lib/net46/
mkdir -p nupkg/lib/net47/
cp DeepSpeechClient/bin/nuget/x64/v4.7/DeepSpeechClient.dll nupkg/lib/net47/
mkdir -p nupkg/lib/uap10.0/
cp DeepSpeechClient/bin/nuget/x64/uap10.0/DeepSpeechClient.dll nupkg/lib/uap10.0/
PROJECT_VERSION=$(strip "${DS_VERSION}")
sed \
-e "s/\$NUPKG_ID/${PROJECT_NAME}/" \
-e "s/\$NUPKG_VERSION/${PROJECT_VERSION}/" \
nupkg/deepspeech.nuspec.in > nupkg/deepspeech.nuspec && cat nupkg/deepspeech.nuspec
nuget pack nupkg/deepspeech.nuspec
}
as well as https://github.com/mozilla/DeepSpeech/blob/51e351e895b845e48f64f2ccb84d3bbb2b0d3379/taskcluster/tc-netframework-ds-tests.sh https://github.com/mozilla/DeepSpeech/blob/51e351e895b845e48f64f2ccb84d3bbb2b0d3379/taskcluster/test-netframework-win-amd64-opt.yml https://github.com/mozilla/DeepSpeech/blob/51e351e895b845e48f64f2ccb84d3bbb2b0d3379/taskcluster/test-netframework-win-cuda-opt.yml https://github.com/mozilla/DeepSpeech/blob/51e351e895b845e48f64f2ccb84d3bbb2b0d3379/taskcluster/test-netframework-win-ttflite-opt.yml

And the final part that will trigger builds

do_deepspeech_netframework_build
do_deepspeech_netframework_wpf_build
do_nuget_build "${PROJECT_NAME}"

@lissyx
Copy link
Collaborator

lissyx commented Oct 13, 2020

@stepkillah It's mostly about bash glue to perform the builds, so you should be able to add your own dotnetcore alternatives and @carlfm01 and myself we can help you working on that.

Given I know nothing about .Net, I can't really judge your current PR and I'm unable to check whether it works or not (no Windows either), so having CI is kind of critical here.

Don't hesitate to reach for help on those matters on Matrix: https://chat.mozilla.org/#/room/#machinelearning:mozilla.org

@stepkillah
Copy link
Collaborator Author

@lissyx thanks a lot for your feedback, I will review/fix PR and will try to set up build and tests for that

@lissyx
Copy link
Collaborator

lissyx commented Oct 13, 2020

@lissyx thanks a lot for your feedback, I will review/fix PR and will try to set up build and tests for that

Thanks @stepkillah ! One thing I thought about after is that you don't provide doc update / dependencies infos, I'm sure we need some ; just to even be able to add missing bits on our CI: https://github.com/mozilla/DeepSpeech/tree/51e351e895b845e48f64f2ccb84d3bbb2b0d3379/native_client/dotnet#building-deepspeech-native-client-for-windows

Copy link
Collaborator

@carlfm01 carlfm01 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR, few questions

¿Have you tested what happens on Linux?
Since we only pack the .so for Windows we need it for non Windows as well, we need the NuGet to be able to unpack the so with the same name as Windows, if the Nuget is not able to unpack with the same name wee need to add conditional compilation or patch NativeImp.cs to select the so to select the name based on the platform.
¿Naudio keeps the same API surface for .NetCore?

moved test sound file to shared folder, using link now
@stepkillah
Copy link
Collaborator Author

stepkillah commented Oct 13, 2020

Thanks for the PR, few questions

¿Have you tested what happens on Linux?
Since we only pack the .so for Windows we need it for non Windows as well, we need the NuGet to be able to unpack the so with the same name as Windows, if the Nuget is not able to unpack with the same name wee need to add conditional compilation or patch NativeImp.cs to select the so to select the name based on the platform.
¿Naudio keeps the same API surface for .NetCore?

Was not able to test it on Linux yet (will try to test it today) but after a closer look - yeah, need to think about how to do it correctly, since net core is cross-platform we need to include so files (cpu and gpu) for - osx, linux, windows, raspberry.
Hope it's possible through build, to avoid adjusting NativeImpl
I will investigate that and will try to adjust build pipeline

Seems like NAudio doesn't work on linux out of the box, so probably will need to adjust the code. I'll check that after running on Linux.

I don't have "full" linux machine, so will use raspberry with raspbian os for test, will it be sufficient?

@stepkillah
Copy link
Collaborator Author

stepkillah commented Oct 13, 2020

@carlfm01 after playing around with libraries I was able to build nuget manually. It unpacking native lib based on runtime, which allows putting .so files with the same name in different folders, and use correct .so at runtime. (can't attach nuget here since it's bigger than 10mb).

Still was not able to test it on Linux because noticed that my raspberry running on linux-arm runtime, which is 32bit, but deployment was successful, an error that occurred for me was exact when lib for a different architecture.
Btw - not sure how to use .so for raspberry cpu from nuget, since for runtime it still will be one of the RID's which already have .so (linux-x64,linux-arm64), but I assume it's an edge case. and a workaround is by replacing .so file after build.

So wondering if I can access all needed .so files for different architectures during call do_nuget_build to generate an updated nuget structure?

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

So wondering if I can access all needed .so files for different architectures during call do_nuget_build to generate an updated nuget structure?

Maybe do like we d o with NodeJS: build platform nuget everywhere, and merge all platforms after?

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

I don't have "full" linux machine, so will use raspberry with raspbian os for test, will it be sufficient?

I'm not sure we should focus all our energy on linux right now for .Net, and please keep in mind that libdeepspeech for linux/armv7 and linux/aarch64 is cross-compiled, we don't build on native hardware (too slow).

Can't you also rely on cross-compilation ?

@stepkillah
Copy link
Collaborator Author

So wondering if I can access all needed .so files for different architectures during call do_nuget_build to generate an updated nuget structure?

Maybe do like we d o with NodeJS: build platform nuget everywhere, and merge all platforms after?

Not sure what is the best way to accomplish this, but we need to do it before packing nuget here. That's seems to be a good place to insert additional dll's and .so.

so we basically need to adjust build steps to be able to create a similar folder structure
image

Also question - do we need to separate net core from net framework builds? I don't see too much difference, but if it will be the same build - probably need to update its name

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

Also question - do we need to separate net core from net framework builds? I don't see too much difference, but if it will be the same build - probably need to update its name

If you want to be able to handle building on linux, you will need to. This way you can add calls on linux build scripts.

Not sure what is the best way to accomplish this, but we need to do it before packing nuget here. That's seems to be a good place to insert additional dll's and .so.

Just consider we can add a new taskcluster task that just does the nuget pack step, pulling .so from other task.

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

But again I'd really prefer if we could avoid over complexify the problem here. Maybe you can just add the .Net Core support to Windows and from there we can figure out how to support all Linux flavors.

@stepkillah
Copy link
Collaborator Author

I don't have "full" linux machine, so will use raspberry with raspbian os for test, will it be sufficient?

I'm not sure we should focus all our energy on linux right now for .Net, and please keep in mind that libdeepspeech for linux/armv7 and linux/aarch64 is cross-compiled, we don't build on native hardware (too slow).

Can't you also rely on cross-compilation ?

Actually Linux it's the main reason for doing it :)

hm, not completely sure how cross-compiling works, but if .so file that nuget contains will work on the target platform - that shouldn't be a problem. for example, .so file for amd64.cpu.linux - it's seems to be linux-x64 runtime, and arm64.cpu.linux it's linux-arm64 etc.

@stepkillah
Copy link
Collaborator Author

But again I'd really prefer if we could avoid over complexify the problem here. Maybe you can just add the .Net Core support to Windows and from there we can figure out how to support all Linux flavors.

I'm also interested to avoid complexity, so trying to find the easiest and effortless way to do that, and for now, it seems like the easiest way is to update the current steps by:
do_deepspeech_netframework_build - add builds for more runtimes (Linux,arm) and then in do_nuget_build pack it with appropriate .so files. that's should be enough to make it work in net core on all basic platforms like win, osx, linux..

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

Actually Linux it's the main reason for doing it :)

You should have mentionned that from the start, because supporting that usecase is a whole lot more efforts CI wise.

hm, not completely sure how cross-compiling works,

Please read the docs, the tc-build-utils.sh script as well as the makefiles.

I have no idea how .Net Core works on linux, and not even how/if it can handle cross compilation. But the thing tht we cannot do is native build on ARM hardware.

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

it seems like the easiest way is to update the current steps by:
do_deepspeech_netframework_build - add builds for more runtimes (Linux,arm)

It was my understanding that Net Framework was Windows only ?

But i advise strongly against updating and i really prefer we have a different codepath for Net Core.

@lissyx
Copy link
Collaborator

lissyx commented Oct 14, 2020

Remember also that each flavor you add will require testing on the CI, and this can be a lot of efforts.

@stepkillah
Copy link
Collaborator Author

It was my understanding that Net Framework was Windows only ?

you're right, but the build process is very similar, for this case, it seems just a matter of replacing TargetFramework here (example) for new net core steps to be netcoreapp3.1 and netstandard2.1

@lissyx
Copy link
Collaborator

lissyx commented Jan 23, 2021

@stepkillah try to update the base image to 18.04: https://github.com/mozilla/DeepSpeech/blob/master/.taskcluster.yml#L56
if it fixes, please send a PR, it might just be because of Python 3.5

@lissyx great, that worked, thanks a lot :)

Please send a separate PR to fix that, against both branch r0.9 as well as master

@lissyx
Copy link
Collaborator

lissyx commented Jan 25, 2021

@stepkillah FTR I have cherry-picked your commit for master and merged this, and fixed the decision task on r0.9 as well, please rebase when you can :)

@stepkillah
Copy link
Collaborator Author

stepkillah commented Jan 25, 2021

merge again, my IDE did this automatically this time, sorry for not rebase, but seems to be good

@lissyx
Copy link
Collaborator

lissyx commented Feb 16, 2021

merge again, my IDE did this automatically this time, sorry for not rebase, but seems to be good

Can you rebase on current master, fix the conflicts, and ensure you have some clear history?

@lissyx
Copy link
Collaborator

lissyx commented Feb 16, 2021

merge again, my IDE did this automatically this time, sorry for not rebase, but seems to be good

Can you rebase on current master, fix the conflicts, and ensure you have some clear history?

Clear history is crucial, otherwise your PR does not really trigger correctly because of your merge commit.

@lissyx
Copy link
Collaborator

lissyx commented Feb 16, 2021

BTW @stepkillah I'm sorry but I don't see any of the last review comments I left being addressed. I can understand you're busy, can you just confirm me whether this is expected or not ? Do you need more help to complete the PR ?

@lissyx
Copy link
Collaborator

lissyx commented Mar 15, 2021

@stepkillah Sorry, we are now going to move out of TaskCluster as highlighted on #3317. it might not be such a big deal in your case, but I don't know yet the extends of the change to GitHub Actions for Windows side.

Sorry about this extra work, I understand you already spent a lot of time on that. I will have a new pass of review with this in mind. You might also want to have a look at their guides: https://docs.github.com/en/actions/guides

We hope it will make it easier for people like you to contribute ! :)

Happy to review changes :)

@@ -0,0 +1,14 @@
build:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@@ -0,0 +1,20 @@
#!/bin/bash
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This script might still be useful for GitHub Actions

@@ -0,0 +1,11 @@
build:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@@ -0,0 +1,79 @@
$if: 'event.event in build.allowed'
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@@ -0,0 +1,12 @@
build:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@@ -0,0 +1,10 @@
#!/bin/bash
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might still have value for GitHub Actions

@@ -342,6 +342,29 @@ run_netframework_inference_tests()
assert_working_ldc93s1_lm "${phrase_pbmodel_withlm}" "$?"
}

run_netcore_inference_tests()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we are still using that as much as I can state

@@ -302,6 +305,61 @@ do_deepspeech_netframework_wpf_build()

}


do_deepspeech_netstandard_build()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might still be usefil for GitHub Actions

@@ -337,6 +410,77 @@ do_nuget_build()
nuget pack nupkg/deepspeech.nuspec
}

do_nuget_repackage()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@@ -62,3 +77,10 @@ get_dep_nuget_pkg_url()
# This should not be reached, otherwise it means we could not find a matching nodejs package
exit 1
}


get_all_deps_from_task()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this will not be useful anymore with GitHub Actions.

@lissyx
Copy link
Collaborator

lissyx commented Mar 15, 2021

@stepkillah If you are okay, we are going to try with @reuben to start laying the basis for GitHub Actions very soon (I'm working on my fork for now), and maybe you might want to stick to only one platform to land this for now, but leverage the easier hackability of GitHub Actions to cover more software and hardware later.

Your feedback on how such a mess our current CI is could be very valuable into simplifying as part of GitHub Actions :)

@stepkillah
Copy link
Collaborator Author

@lissyx yeah, there is no point to target one platform with netcore or netstandard, so I can create separate PR using github actions when you finish the initial fork. Code itself it's not a problem at all, or net core/netstandard support, the main problem here (for me at least 😄 ) is to build it using taskcluster. I think/hope it will be much easier with github actions, so it make sense to wait until initial migration to new CI is completed

@lissyx
Copy link
Collaborator

lissyx commented Mar 15, 2021

@lissyx yeah, there is no point to target one platform with netcore or netstandard, so I can create separate PR using github actions when you finish the initial fork. Code itself it's not a problem at all, or net core/netstandard support, the main problem here (for me at least smile ) is to build it using taskcluster. I think/hope it will be much easier with github actions, so it make sense to wait until initial migration to new CI is completed

If you agree, then you can fix your PR by removing the TaskCluster bits for now, and we merge that (with green TC of course for now) and within a few days when GitHub Actions is live you can pick up :)

@lissyx
Copy link
Collaborator

lissyx commented Mar 19, 2021

@stepkillah If you want to have a look, #3563 :)

@lissyx
Copy link
Collaborator

lissyx commented Mar 25, 2021

@stepkillah Gentle ping, I've merged the first GitHub Actions bit :)

@waf
Copy link

waf commented Jul 2, 2021

I would love to see this PR finished off so I can use DeepSpeech in my applications. I'd be happy to help out with getting GitHub Actions CI finished. Is that the only thing left?

If so, I could create a new PR based on the latest master, and re-use the project/code changes from this branch, and not worry about the taskcluster changes, right? Or if @stepkillah plans to come back to this, I can hold off.

@stepkillah
Copy link
Collaborator Author

@lissyx hello, a long time has passed since this pr was created :) is there a chance we can finish PR? I see it uses GitHub Actions - I can try to adjust the pipeline, but I didn't find where particularly dotnet builds

@Davilink
Copy link

Maybe we should consider moving the effort to coqui instead of deepspeech ?
coqui-ai/STT#2027

@ftyers
Copy link
Collaborator

ftyers commented Jul 26, 2022

DeepSpeech is unmaintained, see #3693.

@ftyers ftyers closed this Jul 26, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants