Skip to content

Android deployment #194

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

Merged
merged 30 commits into from
Jul 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
035fc31
add android loader
amakropoulos Jun 28, 2024
f9efdd8
add android postprocessor
amakropoulos Jun 28, 2024
61a00bb
function to determine the number of big cores in Android
amakropoulos Jul 12, 2024
f1971e2
use the number of big cores if on Android
amakropoulos Jul 12, 2024
1a84e1f
cap big cores at processorCount
amakropoulos Jul 12, 2024
1170b0f
detect big cores based on max frequency
amakropoulos Jul 17, 2024
983df38
demo android
amakropoulos Jul 17, 2024
0b25458
move arguments to Awake
amakropoulos Jul 17, 2024
afa86b2
demo android
amakropoulos Jul 17, 2024
4e6d39c
android demo sample
amakropoulos Jul 17, 2024
aab7b11
downloader with resume capabilities
amakropoulos Jul 18, 2024
aed6af3
use resume downloader in LLMUnitySetup
amakropoulos Jul 18, 2024
665f903
adapt tests to download changes
amakropoulos Jul 18, 2024
a003f3e
use alpaca template, larger x, connect buttons
amakropoulos Jul 19, 2024
7d05329
move model download to LLM
amakropoulos Jul 19, 2024
e1bbb04
use LLM download
amakropoulos Jul 19, 2024
450aedb
set template, use short args for download
amakropoulos Jul 19, 2024
ee9d050
check if all bytes are downloaded before starting
amakropoulos Jul 20, 2024
d5bd618
download on start functionality
amakropoulos Jul 20, 2024
44ba7f2
add model url if download on build
amakropoulos Jul 20, 2024
d1e3d34
wait on download, server ready
amakropoulos Jul 20, 2024
80b5221
show progress
amakropoulos Jul 20, 2024
8ca4b79
download on build
amakropoulos Jul 21, 2024
bc6e019
set template only when started
amakropoulos Jul 21, 2024
f1955fd
use symlinks instaed of copying
amakropoulos Jul 22, 2024
afad390
move models if using URL
amakropoulos Jul 22, 2024
32ab6ef
add function to extract files from APK
amakropoulos Jul 22, 2024
8138257
add lora and model download attributes
amakropoulos Jul 22, 2024
82be503
download or extract model and lora
amakropoulos Jul 22, 2024
5833951
do not change template when downloading models at start
amakropoulos Jul 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 58 additions & 43 deletions Editor/LLMBuildProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,28 @@

namespace LLMUnity
{
public class LLMBuildProcessor : IPreprocessBuildWithReport, IPostprocessBuildWithReport
public class LLMBuildProcessor : MonoBehaviour, IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
public int callbackOrder => 0;
static string tempDir = Path.Combine(Application.temporaryCachePath, "LLMBuildProcessor", Path.GetFileName(LLMUnitySetup.libraryPath));
static string foldersMovedCache = Path.Combine(tempDir, "moved.json");
static List<MovedPair> movedPairs = new List<MovedPair>();
static string movedCache = Path.Combine(tempDir, "moved.json");

[InitializeOnLoadMethod]
private static void InitializeOnLoad()
{
if (!Directory.Exists(tempDir)) Directory.CreateDirectory(tempDir);
else ResetLibraryPlatforms();
else ResetMoves();
}

// CALLED BEFORE THE BUILD
public void OnPreprocessBuild(BuildReport report)
{
// Start listening for errors when build starts
Application.logMessageReceived += OnBuildError;
List<string> platforms = GetLibraryPlatformsToHide(report.summary.platform);
HideLibraryPlatforms(platforms);
HideLibraryPlatforms(report.summary.platform);
HideModels();
if (movedPairs.Count > 0) AssetDatabase.Refresh();
}

// CALLED DURING BUILD TO CHECK FOR ERRORS
Expand All @@ -49,29 +51,10 @@ public void OnPostprocessBuild(BuildReport report)
public void BuildCompleted()
{
Application.logMessageReceived -= OnBuildError;
ResetLibraryPlatforms();
ResetMoves();
}

static List<string> GetLibraryPlatformsToHide(BuildTarget platform)
{
List<string> platforms = new List<string>(){ "windows", "macos", "linux" };
switch (platform)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
platforms.Remove("windows");
break;
case BuildTarget.StandaloneLinux64:
platforms.Remove("linux");
break;
case BuildTarget.StandaloneOSX:
platforms.Remove("macos");
break;
}
return platforms;
}

static bool MovePath(string source, string target, List<FoldersMovedPair> foldersMoved = null)
static bool MovePath(string source, string target)
{
bool moved = false;
if (File.Exists(source))
Expand All @@ -84,45 +67,77 @@ static bool MovePath(string source, string target, List<FoldersMovedPair> folder
Directory.Move(source, target);
moved = true;
}
if (moved && foldersMoved != null) foldersMoved.Add(new FoldersMovedPair {source = source, target = target});
if (moved)
{
movedPairs.Add(new MovedPair {source = source, target = target});
File.WriteAllText(movedCache, JsonUtility.ToJson(new FoldersMovedWrapper { movedPairs = movedPairs }));
}
return moved;
}

static void HideLibraryPlatforms(List<string> platforms)
static void MoveAssetAndMeta(string source, string target)
{
MovePath(source + ".meta", target + ".meta");
MovePath(source, target);
}

static void HideLibraryPlatforms(BuildTarget buildPlatform)
{
List<FoldersMovedPair> foldersMoved = new List<FoldersMovedPair>();
List<string> platforms = new List<string>(){ "windows", "macos", "linux", "android" };
switch (buildPlatform)
{
case BuildTarget.StandaloneWindows:
case BuildTarget.StandaloneWindows64:
platforms.Remove("windows");
break;
case BuildTarget.StandaloneLinux64:
platforms.Remove("linux");
break;
case BuildTarget.StandaloneOSX:
platforms.Remove("macos");
break;
case BuildTarget.Android:
platforms.Remove("android");
break;
}

foreach (string dirname in Directory.GetDirectories(LLMUnitySetup.libraryPath))
{
foreach (string platform in platforms)
{
if (Path.GetFileName(dirname).StartsWith(platform))
{
string movePath = Path.Combine(tempDir, Path.GetFileName(dirname));
MovePath(dirname + ".meta", movePath + ".meta", foldersMoved);
MovePath(dirname, movePath, foldersMoved);
File.WriteAllText(foldersMovedCache, JsonUtility.ToJson(new FoldersMovedWrapper { foldersMoved = foldersMoved }));
MoveAssetAndMeta(dirname, Path.Combine(tempDir, Path.GetFileName(dirname)));
}
}
}
if (foldersMoved.Count > 0) AssetDatabase.Refresh();
}

static void ResetLibraryPlatforms()
static void HideModels()
{
foreach (LLM llm in FindObjectsOfType<LLM>())
{
if (!llm.downloadOnBuild) continue;
if (llm.modelURL != "") MoveAssetAndMeta(LLMUnitySetup.GetAssetPath(llm.model), Path.Combine(tempDir, Path.GetFileName(llm.model)));
if (llm.loraURL != "") MoveAssetAndMeta(LLMUnitySetup.GetAssetPath(llm.lora), Path.Combine(tempDir, Path.GetFileName(llm.lora)));
}
}

static void ResetMoves()
{
if (!File.Exists(foldersMovedCache)) return;
List<FoldersMovedPair> foldersMoved = JsonUtility.FromJson<FoldersMovedWrapper>(File.ReadAllText(foldersMovedCache)).foldersMoved;
if (foldersMoved == null) return;
if (!File.Exists(movedCache)) return;
List<MovedPair> movedPairs = JsonUtility.FromJson<FoldersMovedWrapper>(File.ReadAllText(movedCache)).movedPairs;
if (movedPairs == null) return;

bool refresh = false;
foreach (var pair in foldersMoved) refresh |= MovePath(pair.target, pair.source);
foreach (var pair in movedPairs) refresh |= MovePath(pair.target, pair.source);
if (refresh) AssetDatabase.Refresh();

File.Delete(foldersMovedCache);
File.Delete(movedCache);
}
}

[Serializable]
public struct FoldersMovedPair
public struct MovedPair
{
public string source;
public string target;
Expand All @@ -131,6 +146,6 @@ public struct FoldersMovedPair
[Serializable]
public class FoldersMovedWrapper
{
public List<FoldersMovedPair> foldersMoved;
public List<MovedPair> movedPairs;
}
}
9 changes: 6 additions & 3 deletions Editor/LLMEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void AddModelLoaders(SerializedObject llmScriptSO, LLM llmScript)
int newIndex = EditorGUILayout.Popup("Model", llmScript.SelectedModel, options);
if (newIndex != llmScript.SelectedModel)
{
LLMUnitySetup.DownloadModel(llmScript, newIndex);
llmScript.DownloadDefaultModel(newIndex);
}

if (GUILayout.Button("Load model", GUILayout.Width(buttonWidth)))
Expand All @@ -45,7 +45,7 @@ public void AddModelLoaders(SerializedObject llmScriptSO, LLM llmScript)
string path = EditorUtility.OpenFilePanelWithFilters("Select a gguf model file", "", new string[] { "Model Files", "gguf" });
if (!string.IsNullOrEmpty(path))
{
llmScript.SelectedModel = 0;
llmScript.ResetSelectedModel();
llmScript.SetModel(path);
}
};
Expand Down Expand Up @@ -86,11 +86,14 @@ public void AddModelAddonLoaders(SerializedObject llmScriptSO, LLM llmScript, bo
public void AddModelSettings(SerializedObject llmScriptSO)
{
List<Type> attributeClasses = new List<Type> { typeof(ModelAttribute) };
List<Type> excludeAttributeClasses = new List<Type> { typeof(ModelDownloadAttribute), typeof(ModelDownloadAdvancedAttribute) };
if (llmScriptSO.FindProperty("downloadOnBuild").boolValue) excludeAttributeClasses.Remove(typeof(ModelDownloadAttribute));
if (llmScriptSO.FindProperty("advancedOptions").boolValue)
{
attributeClasses.Add(typeof(ModelAdvancedAttribute));
if (llmScriptSO.FindProperty("downloadOnBuild").boolValue) excludeAttributeClasses.Remove(typeof(ModelDownloadAdvancedAttribute));
}
ShowPropertiesOfClass("", llmScriptSO, attributeClasses, false);
ShowPropertiesOfClass("", llmScriptSO, attributeClasses, false, excludeAttributeClasses);
Space();
}

Expand Down
17 changes: 15 additions & 2 deletions Editor/PropertyEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,10 +94,23 @@ public List<SerializedProperty> GetPropertiesOfClass(SerializedObject so, List<T
return properties;
}

public void ShowPropertiesOfClass(string title, SerializedObject so, List<Type> attributeClasses, bool addSpace = true)
public void ShowPropertiesOfClass(string title, SerializedObject so, List<Type> attributeClasses, bool addSpace = true, List<Type> excludeAttributeClasses = null)
{
// display a property if it belongs to a certain class and/or has a specific attribute class
List<SerializedProperty> properties = GetPropertiesOfClass(so, attributeClasses);
if (excludeAttributeClasses != null)
{
List<SerializedProperty> excludeProperties = GetPropertiesOfClass(so, excludeAttributeClasses);
List<SerializedProperty> removeProperties = new List<SerializedProperty>();
foreach (SerializedProperty excprop in excludeProperties)
{
foreach (SerializedProperty prop in properties)
{
if (prop.displayName == excprop.displayName) removeProperties.Add(prop);
}
}
foreach (SerializedProperty prop in removeProperties) properties.Remove(prop);
}
if (properties.Count == 0) return;
if (title != "") EditorGUILayout.LabelField(title, EditorStyles.boldLabel);
foreach (SerializedProperty prop in properties)
Expand Down Expand Up @@ -141,7 +154,7 @@ public Attribute GetPropertyAttribute(SerializedProperty prop, Type attributeCla
{
foreach (Attribute attr in fieldInfo.GetCustomAttributes(attributeClass, true))
{
if (attr.GetType() == attributeClass)
if (attributeClass.IsAssignableFrom(attr.GetType()))
return attr;
}
}
Expand Down
Loading
Loading