LLM for Unity  v3.0.1
Create characters in Unity with LLMs!
Loading...
Searching...
No Matches
LLMUtils.cs
Go to the documentation of this file.
1
3using System;
4using System.Collections.Generic;
5using System.Threading;
6using UndreamAI.LlamaLib;
7using UnityEngine;
8
9namespace LLMUnity
10{
15 public class LLMException : Exception
16 {
17 public int ErrorCode { get; private set; }
18
19 public LLMException(string message, int errorCode) : base(message)
20 {
21 ErrorCode = errorCode;
22 }
23 }
24
29 public class DestroyException : Exception {}
30
35 public class LoraAsset
36 {
37 public string assetPath;
38 public string fullPath;
39 public float weight;
40
41 public LoraAsset(string path, float weight = 1)
42 {
43 assetPath = LLM.GetLLMManagerAsset(path);
44 fullPath = RuntimePath(path);
45 this.weight = weight;
46 }
47
48 public static string RuntimePath(string path)
49 {
50 return LLMUnitySetup.GetFullPath(LLM.GetLLMManagerAssetRuntime(path));
51 }
52 }
53
58 public class LoraManager
59 {
60 List<LoraAsset> loras = new List<LoraAsset>();
61 public string delimiter = ",";
62
66 public void Clear()
67 {
68 loras.Clear();
69 }
70
76 public int IndexOf(string path)
77 {
78 string fullPath = LoraAsset.RuntimePath(path);
79 for (int i = 0; i < loras.Count; i++)
80 {
81 LoraAsset lora = loras[i];
82 if (lora.assetPath == path || lora.fullPath == fullPath) return i;
83 }
84 return -1;
85 }
86
92 public bool Contains(string path)
93 {
94 return IndexOf(path) != -1;
95 }
96
102 public void Add(string path, float weight = 1)
103 {
104 if (Contains(path)) return;
105 loras.Add(new LoraAsset(path, weight));
106 }
107
112 public void Remove(string path)
113 {
114 int index = IndexOf(path);
115 if (index != -1) loras.RemoveAt(index);
116 }
117
123 public void SetWeight(string path, float weight)
124 {
125 int index = IndexOf(path);
126 if (index == -1)
127 {
128 LLMUnitySetup.LogError($"LoRA {path} not loaded with the LLM");
129 return;
130 }
131 loras[index].weight = weight;
132 }
133
139 public void FromStrings(string loraString, string loraWeightsString)
140 {
141 if (string.IsNullOrEmpty(loraString) && string.IsNullOrEmpty(loraWeightsString))
142 {
143 Clear();
144 return;
145 }
146
147 try
148 {
149 List<string> loraStringArr = new List<string>(loraString.Split(delimiter));
150 List<string> loraWeightsStringArr = new List<string>(loraWeightsString.Split(delimiter));
151 if (loraStringArr.Count != loraWeightsStringArr.Count) LLMUnitySetup.LogError($"LoRAs number ({loraString}) doesn't match the number of weights ({loraWeightsString})", true);
152
153 List<LoraAsset> lorasNew = new List<LoraAsset>();
154 for (int i = 0; i < loraStringArr.Count; i++) lorasNew.Add(new LoraAsset(loraStringArr[i].Trim(), float.Parse(loraWeightsStringArr[i])));
155 loras = lorasNew;
156 }
157 catch (Exception e)
158 {
159 LLMUnitySetup.LogError($"Loras not set: {e.Message}");
160 }
161 }
162
167 public (string, string) ToStrings()
168 {
169 string loraString = "";
170 string loraWeightsString = "";
171 for (int i = 0; i < loras.Count; i++)
172 {
173 if (i > 0)
174 {
175 loraString += delimiter;
176 loraWeightsString += delimiter;
177 }
178 loraString += loras[i].assetPath;
179 loraWeightsString += loras[i].weight;
180 }
181 return (loraString, loraWeightsString);
182 }
183
188 public float[] GetWeights()
189 {
190 float[] weights = new float[loras.Count];
191 for (int i = 0; i < loras.Count; i++) weights[i] = loras[i].weight;
192 return weights;
193 }
194
199 public string[] GetLoras()
200 {
201 string[] loraPaths = new string[loras.Count];
202 for (int i = 0; i < loras.Count; i++) loraPaths[i] = loras[i].assetPath;
203 return loraPaths;
204 }
205 }
206
207 public class Utils
208 {
209 // Extract main thread wrapping logic
210 public static Action<string> WrapActionForMainThread(
211 Action<string> callback, MonoBehaviour owner)
212 {
213 if (callback == null) return null;
214 var context = SynchronizationContext.Current;
215
216 return msg =>
217 {
218 try
219 {
220 if (owner == null) return;
221 if (context != null)
222 {
223 context.Post(_ =>
224 {
225 try
226 {
227 if (owner != null) callback(msg);
228 }
229 catch (Exception e)
230 {
231 LLMUnitySetup.LogError($"Exception in callback: {e}");
232 }
233 }, null);
234 }
235 else
236 {
237 callback(msg);
238 }
239 }
240 catch (Exception e)
241 {
242 LLMUnitySetup.LogError($"Exception in callback wrapper: {e}");
243 }
244 };
245 }
246
247#if !ENABLE_IL2CPP
248 // Keep original for Mono builds
249 public static LlamaLib.CharArrayCallback WrapCallbackForAsync(
250 Action<string> callback, MonoBehaviour owner)
251 {
252 if (callback == null) return null;
253 Action<string> mainThreadCallback = WrapActionForMainThread(callback, owner);
254 return msg => mainThreadCallback(msg);
255 }
256
257#endif
258 }
260}
Class implementing a basic LLM Destroy Exception.
Definition LLMUtils.cs:29
Class implementing a basic LLM Exception.
Definition LLMUtils.cs:16
Class implementing helper functions for setup and process management.
Unity MonoBehaviour component that manages a local LLM server instance. Handles model loading,...
Definition LLM.cs:21
Class representing a LORA asset.
Definition LLMUtils.cs:36
Class representing the LORA manager allowing to convert and retrieve LORA assets to string (for seria...
Definition LLMUtils.cs:59
float[] GetWeights()
Gets the weights of the LORAs in the manager.
Definition LLMUtils.cs:188
void Add(string path, float weight=1)
Adds a LORA with the defined weight.
Definition LLMUtils.cs:102
void Remove(string path)
Removes a LORA based on its path.
Definition LLMUtils.cs:112
int IndexOf(string path)
Searches for a LORA based on the path.
Definition LLMUtils.cs:76
void SetWeight(string path, float weight)
Modifies the weight of a LORA.
Definition LLMUtils.cs:123
void FromStrings(string loraString, string loraWeightsString)
Converts strings with the lora paths and weights to entries in the LORA manager.
Definition LLMUtils.cs:139
string
Converts the entries of the LORA manager to strings with the lora paths and weights.
Definition LLMUtils.cs:167
bool Contains(string path)
Checks if the provided LORA based on a path exists already in the LORA manager.
Definition LLMUtils.cs:92
string[] GetLoras()
Gets the paths of the LORAs in the manager.
Definition LLMUtils.cs:199
void Clear()
Clears the LORA assets.
Definition LLMUtils.cs:66