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

Android Backend Support #717

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

AmSmart
Copy link

@AmSmart AmSmart commented May 4, 2024

As discussed in #695, Here's a PR that generates the shared library for Android. I have also added the new binaries to be copied in the CPU Backend .nuspec file. Please let me know if I am missing anything else.

I have tested the generated .so by loading manually into a .NET MAUI app which ran smoothly on my Android device. See video below

Screen_Recording_20240427_141010.mp4

@martindevans
Copy link
Collaborator

Looks good, thanks for putting this together.

Could you please manually trigger a run of the "Update Binaries" action on your repo as a test run. To do that:

  1. Go to actions (top bar of your repo)
  2. Select "Update Binaries" on the left
  3. Click "Run Workflow" at the top of the run list (right side)
  4. Change the branch to add-android-support
  5. Click run workflow
  6. Link the run here

Copy link
Collaborator

@AsakusaRinne AsakusaRinne left a comment

Choose a reason for hiding this comment

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

Thank you for this contribution! The overall looks good except one concern. I prefer to putting the android native libraries in a new package LLamaSharp.Backend.Android because those who want to use android will never use libraries of win/linux/osx. For those who want to publish a cross-platform app, they could install both LLamaSharp.Backend.Android and LLamaSharp.Backend.Cpu. Please refer to #489 to see how to add a new backend package.

The following items will further improve it but are not required in this PR.

  1. Add a workflow to run test in android. I know little about running C# apps on android but it seems that github action has already provided such support (reference).
  2. Add logics to support dynamic native library selection on android.

I'd like to work with item 2 after having this PR merged so please don't worry about it. :) Would you like to work with item 1 (in this PR or after this PR are both okay).

@AmSmart
Copy link
Author

AmSmart commented May 7, 2024

Totally aligned. I was pondering that it deserved its own backend as well but wasn't sure. Will work on these over the next few days. Should share an update soon.

PS: Prefer to finish it up in this PR

@cmpktheo
Copy link

Could you upload the MAUI app's source with the android runtime libraries to test it?

@AmSmart
Copy link
Author

AmSmart commented May 24, 2024

Hi @cmpktheo Attaching a binary compliled for android-arm64-v8a

libllama.zip

@cmpktheo
Copy link

Thanks @AmSmart !
I have been trying to build llama.cpp on a linux VM and test a MAUI Android app with LlamaSharp using a Visual Studio x86_64 emulator.

I followed the android build instructions on llama.cpp page, but when I try to use the .so file, I get a null pointer calling the llama_model_default_params method (which basically returns a dummy structure) . It makes me think that there's either a flaw in my build process or some issue related to MAUI. This is my first attempt to build anything in MAUI so I might miss something.
I've created a windows MAUI app that loads the GPT2 guff model and works perfectly.

I would appreciate if you could share the build process so I can apply it to x86_64 architecture or a ready build x86_64 runtime and ideally a MAUI-Android sample app.

@martindevans
Copy link
Collaborator

@cmpktheo did you ensure you're using the right version of llama.cpp? The C# source is only compatible with one exact version! See the table in the readme here for the correct versions.

@cmpktheo
Copy link

@martindevans the issue seems to be with my build process since the native method returns null pointer.

@AmSmart AmSmart force-pushed the feature/add-android-support branch from 82e5020 to cb08e1b Compare May 29, 2024 18:58
@AmSmart AmSmart force-pushed the feature/add-android-support branch from cb08e1b to c7b6980 Compare May 29, 2024 19:37
@AmSmart
Copy link
Author

AmSmart commented May 29, 2024

@cmpktheo You can check the compile.yml file from my PR. I've updated it to include other Android architectures.

@AmSmart AmSmart force-pushed the feature/add-android-support branch from 7541e8b to 0511b96 Compare May 29, 2024 21:25
@AmSmart
Copy link
Author

AmSmart commented May 29, 2024

@AsakusaRinne I've been a bit busy since our last conversation but I've finally gotten some time to address some of the concerns you listed earlier and made some other changes as well.

Things to note

  • I have created a different Nuspec for the Android backend as discussed
  • I noticed there was a .targets file but it wasn't been used by any of the generated packages (I double checked this by unzipping existing packages on Nuget). That said, I needed the targets file to Embed the library and link for Android so I removed all the dormant build directives in the file and have just the Android ones in it. I plan to open another PR for iOS and it would need the targets file as well. If you do not like these change, or need a bit more clarification. I'm happy to explain more
  • Since Android doesn't support additional enhancements (CUDA, CUBLAS, AVX etc) at the moment, there is really no need to manually resolve the native library. I have added an if statement to exclude Android from the Manual Resolution in NativeApi.Load.cs
  • Updated the compile.yml file to remove file extensions from directory names. I think it may confuse new contributors who may confuse the directories for files (I was confused for a moment).
  • With regards to providing tests, I'm thinking of a world where we have a Demo/Example .NET Android Project instead. The UnitTests already provide coverage for the underlying code and a demo app should suffice. That said, we could still proceed to write tests against the demo app and have them run in the workflow. Let me know what you think, I'm happy to contribute this in another PR.

Let me know if there are anymore requested changes for this PR to be good to go.

Copy link
Collaborator

@AsakusaRinne AsakusaRinne left a comment

Choose a reason for hiding this comment

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

Thank you for your effort! It looks good to me except a few minor issues.

With regards to providing tests, I'm thinking of a world where we have a Demo/Example .NET Android Project instead. The UnitTests already provide coverage for the underlying code and a demo app should suffice. That said, we could still proceed to write tests against the demo app and have them run in the workflow. Let me know what you think, I'm happy to contribute this in another PR.

Sure, the workflow is not required in this PR. It's a good idea to add an example/demo first. The main motivation for the android test workflow is that our core team members do not have android environment to test it. Thus it will be hard for us to know whether a PR breaks this feature. But no hurry, adding an example is a good first step. :)

Since Android doesn't support additional enhancements (CUDA, CUBLAS, AVX etc) at the moment, there is really no need to manually resolve the native library. I have added an if statement to exclude Android from the Manual Resolution in NativeApi.Load.cs

The native library loading system is also responsible for deciding the file path to load it. However, please don't worry, I'll do it after this PR.


<None Include="$(MSBuildThisFileDirectory)runtimes/deps/llama.dll">
Copy link
Collaborator

Choose a reason for hiding this comment

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

These targets are used in the unittest and example projects, for example:

https://github.com/SciSharp/LLamaSharp/blob/master/LLama.Examples/LLama.Examples.csproj#L2

https://github.com/SciSharp/LLamaSharp/blob/master/LLama.Unittest/LLama.Unittest.csproj#L2

Therefore, though I'm not sure whether this targets file should also be used in other backend packages, I don't think we should remove it. May I ask which behavior will be different if a targets file is used in the backend package?

@@ -57,6 +57,11 @@ private static void SetDllImportResolver()
// NativeLibrary is not available on older runtimes. We'll have to depend on
// the normal runtime dll resolution there.
#if NET5_0_OR_GREATER

// We don't need special dll resolution on Android
if (OperatingSystem.IsAndroid())
Copy link
Collaborator

Choose a reason for hiding this comment

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

The master branch has refactored the native library loading system so I'm afraid this code would not work. Don't worry, I can do it after having this PR merged.

@@ -51,12 +51,12 @@ jobs:
- uses: actions/upload-artifact@v4
with:
path: ./build/libllama.so
name: llama-bin-linux-${{ matrix.build }}-x64.so
name: llama-bin-linux-${{ matrix.build }}-x64
Copy link
Collaborator

Choose a reason for hiding this comment

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

@martindevans Could you please take a look of this? I'm not sure what it's expected to do with the original code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants