5using System.Collections.Generic;
7using System.Runtime.InteropServices;
16 public class StreamWrapper
19 Callback<string> callback;
21 string previousString =
"";
22 string previousCalledString =
"";
23 int previousBufferSize = 0;
26 public StreamWrapper(LLMLib llmlib, Callback<string> callback,
bool clearOnUpdate =
false)
29 this.callback = callback;
30 this.clearOnUpdate = clearOnUpdate;
31 stringWrapper = (llmlib?.StringWrapper_Construct()).GetValueOrDefault();
39 public string GetString(
bool clear =
false)
42 int bufferSize = (llmlib?.StringWrapper_GetStringSize(stringWrapper)).GetValueOrDefault();
47 else if (previousBufferSize != bufferSize)
49 IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
52 llmlib?.StringWrapper_GetString(stringWrapper, buffer, bufferSize, clear);
53 result = Marshal.PtrToStringAnsi(buffer);
57 Marshal.FreeHGlobal(buffer);
59 previousString = result;
63 result = previousString;
65 previousBufferSize = bufferSize;
74 if (stringWrapper == IntPtr.Zero)
return;
75 string result = GetString(clearOnUpdate);
76 if (result !=
"" && previousCalledString != result)
78 callback?.Invoke(result);
79 previousCalledString = result;
87 public IntPtr GetStringWrapper()
97 if (stringWrapper != IntPtr.Zero) llmlib?.StringWrapper_Delete(stringWrapper);
107 static class LibraryLoader
116 public static T GetSymbolDelegate<T>(IntPtr library,
string name) where T : Delegate
118 var symbol = GetSymbol(library, name);
119 if (symbol == IntPtr.Zero)
120 throw new EntryPointNotFoundException($
"Unable to load symbol '{name}'.");
122 return Marshal.GetDelegateForFunctionPointer<T>(symbol);
130 public static IntPtr LoadLibrary(
string libraryName)
132 if (
string.IsNullOrEmpty(libraryName))
133 throw new ArgumentNullException(nameof(libraryName));
136 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
137 handle = Win32.LoadLibrary(libraryName);
138 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
139 handle = Linux.dlopen(libraryName);
140 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
141 handle = Mac.dlopen(libraryName);
142 else if (Application.platform == RuntimePlatform.Android)
143 handle = Android.dlopen(libraryName);
144 else if (Application.platform == RuntimePlatform.IPhonePlayer)
145 handle = iOS.dlopen(libraryName);
147 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to load library '{libraryName}'.");
158 public static IntPtr GetSymbol(IntPtr library,
string symbolName)
160 if (
string.IsNullOrEmpty(symbolName))
161 throw new ArgumentNullException(nameof(symbolName));
164 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
165 handle = Win32.GetProcAddress(library, symbolName);
166 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
167 handle = Linux.dlsym(library, symbolName);
168 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
169 handle = Mac.dlsym(library, symbolName);
170 else if (Application.platform == RuntimePlatform.Android)
171 handle = Android.dlsym(library, symbolName);
172 else if (Application.platform == RuntimePlatform.IPhonePlayer)
173 handle = iOS.dlsym(library, symbolName);
175 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to load symbol '{symbolName}' from library {library}.");
184 public static void FreeLibrary(IntPtr library)
186 if (library == IntPtr.Zero)
189 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
190 Win32.FreeLibrary(library);
191 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
192 Linux.dlclose(library);
193 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
194 Mac.dlclose(library);
195 else if (Application.platform == RuntimePlatform.Android)
196 Android.dlclose(library);
197 else if (Application.platform == RuntimePlatform.IPhonePlayer)
198 iOS.dlclose(library);
200 throw new PlatformNotSupportedException($
"Current platform is unknown, unable to close library '{library}'.");
203 private static class Mac
205 private const string SystemLibrary =
"/usr/lib/libSystem.dylib";
207 private const int RTLD_LAZY = 1;
208 private const int RTLD_NOW = 2;
210 public static IntPtr dlopen(
string path,
bool lazy =
true) =>
211 dlopen(path, lazy ? RTLD_LAZY : RTLD_NOW);
213 [DllImport(SystemLibrary)]
214 public static extern IntPtr dlopen(
string path,
int mode);
216 [DllImport(SystemLibrary)]
217 public static extern IntPtr dlsym(IntPtr handle,
string symbol);
219 [DllImport(SystemLibrary)]
220 public static extern void dlclose(IntPtr handle);
223 private static class Linux
225 private const string SystemLibrary =
"libdl.so";
226 private const string SystemLibrary2 =
"libdl.so.2";
228 private const int RTLD_LAZY = 1;
229 private const int RTLD_NOW = 2;
231 private static bool UseSystemLibrary2 =
true;
233 public static IntPtr dlopen(
string path,
bool lazy =
true)
237 return dlopen2(path, lazy ? RTLD_LAZY : RTLD_NOW);
239 catch (DllNotFoundException)
241 UseSystemLibrary2 =
false;
242 return dlopen1(path, lazy ? RTLD_LAZY : RTLD_NOW);
246 public static IntPtr dlsym(IntPtr handle,
string symbol)
248 return UseSystemLibrary2 ? dlsym2(handle, symbol) : dlsym1(handle, symbol);
251 public static void dlclose(IntPtr handle)
253 if (UseSystemLibrary2)
259 [DllImport(SystemLibrary, EntryPoint =
"dlopen")]
260 private static extern IntPtr dlopen1(
string path,
int mode);
262 [DllImport(SystemLibrary, EntryPoint =
"dlsym")]
263 private static extern IntPtr dlsym1(IntPtr handle,
string symbol);
265 [DllImport(SystemLibrary, EntryPoint =
"dlclose")]
266 private static extern void dlclose1(IntPtr handle);
268 [DllImport(SystemLibrary2, EntryPoint =
"dlopen")]
269 private static extern IntPtr dlopen2(
string path,
int mode);
271 [DllImport(SystemLibrary2, EntryPoint =
"dlsym")]
272 private static extern IntPtr dlsym2(IntPtr handle,
string symbol);
274 [DllImport(SystemLibrary2, EntryPoint =
"dlclose")]
275 private static extern void dlclose2(IntPtr handle);
278 private static class Win32
280 private const string SystemLibrary =
"Kernel32.dll";
282 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
283 public static extern IntPtr LoadLibrary(
string lpFileName);
285 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
286 public static extern IntPtr GetProcAddress(IntPtr hModule,
string lpProcName);
288 [DllImport(SystemLibrary, SetLastError =
true, CharSet = CharSet.Ansi)]
289 public static extern void FreeLibrary(IntPtr hModule);
292 private static class Android
294 public static IntPtr dlopen(
string path) => dlopen(path, 1);
297 [DllImport(
"__Internal")]
298 public static extern IntPtr dlopen(
string filename,
int flags);
300 [DllImport(
"__Internal")]
301 public static extern IntPtr dlsym(IntPtr handle,
string symbol);
303 [DllImport(
"__Internal")]
304 public static extern int dlclose(IntPtr handle);
306 public static IntPtr dlopen(
string filename,
int flags)
311 public static IntPtr dlsym(IntPtr handle,
string symbol)
316 public static int dlclose(IntPtr handle)
324 private static class iOS
326 public static IntPtr dlopen(
string path) => dlopen(path, 1);
330 [DllImport(
"__Internal")]
331 public static extern IntPtr dlopen(
string filename,
int flags);
334 [DllImport(
"__Internal")]
335 public static extern IntPtr dlsym(IntPtr handle,
string symbol);
338 [DllImport(
"__Internal")]
339 public static extern int dlclose(IntPtr handle);
341 public static IntPtr dlopen(
string filename,
int flags)
346 public static IntPtr dlsym(IntPtr handle,
string symbol)
351 public static int dlclose(IntPtr handle)
366 IntPtr libraryHandle = IntPtr.Zero;
367 static bool has_avx =
false;
368 static bool has_avx2 =
false;
369 static bool has_avx512 =
false;
370 List<IntPtr> dependencyHandles =
new List<IntPtr>();
372#if (UNITY_ANDROID || UNITY_IOS) && !UNITY_EDITOR
374 public LLMLib(
string arch) {}
377 public const string LibraryName =
"libundreamai_android";
379 public const string LibraryName =
"__Internal";
382 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"Logging")]
383 public static extern void LoggingStatic(IntPtr stringWrapper);
384 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StopLogging")]
385 public static extern void StopLoggingStatic();
386 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Construct")]
387 public static extern IntPtr LLM_ConstructStatic(
string command);
388 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Delete")]
389 public static extern void LLM_DeleteStatic(IntPtr LLMObject);
390 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_StartServer")]
391 public static extern void LLM_StartServerStatic(IntPtr LLMObject);
392 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_StopServer")]
393 public static extern void LLM_StopServerStatic(IntPtr LLMObject);
394 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Start")]
395 public static extern void LLM_StartStatic(IntPtr LLMObject);
396 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Started")]
397 public static extern bool LLM_StartedStatic(IntPtr LLMObject);
398 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Stop")]
399 public static extern void LLM_StopStatic(IntPtr LLMObject);
400 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_SetTemplate")]
401 public static extern void LLM_SetTemplateStatic(IntPtr LLMObject,
string chatTemplate);
402 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_SetSSL")]
403 public static extern void LLM_SetSSLStatic(IntPtr LLMObject,
string SSLCert,
string SSLKey);
404 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Tokenize")]
405 public static extern void LLM_TokenizeStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
406 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Detokenize")]
407 public static extern void LLM_DetokenizeStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
408 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Embeddings")]
409 public static extern void LLM_EmbeddingsStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
410 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Lora_Weight")]
411 public static extern void LLM_LoraWeightStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
412 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Lora_List")]
413 public static extern void LLM_LoraListStatic(IntPtr LLMObject, IntPtr stringWrapper);
414 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Completion")]
415 public static extern void LLM_CompletionStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
416 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Slot")]
417 public static extern void LLM_SlotStatic(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
418 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Cancel")]
419 public static extern void LLM_CancelStatic(IntPtr LLMObject,
int idSlot);
420 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"LLM_Status")]
421 public static extern int LLM_StatusStatic(IntPtr LLMObject, IntPtr stringWrapper);
422 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_Construct")]
423 public static extern IntPtr StringWrapper_ConstructStatic();
424 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_Delete")]
425 public static extern void StringWrapper_DeleteStatic(IntPtr instance);
426 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_GetStringSize")]
427 public static extern int StringWrapper_GetStringSizeStatic(IntPtr instance);
428 [DllImport(LibraryName, CallingConvention = CallingConvention.Cdecl, EntryPoint =
"StringWrapper_GetString")]
429 public static extern void StringWrapper_GetStringStatic(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false);
431 public void Logging(IntPtr stringWrapper) { LoggingStatic(stringWrapper); }
432 public void StopLogging() { StopLoggingStatic(); }
433 public IntPtr LLM_Construct(
string command) {
return LLM_ConstructStatic(command); }
434 public void LLM_Delete(IntPtr LLMObject) { LLM_DeleteStatic(LLMObject); }
435 public void LLM_StartServer(IntPtr LLMObject) { LLM_StartServerStatic(LLMObject); }
436 public void LLM_StopServer(IntPtr LLMObject) { LLM_StopServerStatic(LLMObject); }
437 public void LLM_Start(IntPtr LLMObject) { LLM_StartStatic(LLMObject); }
438 public bool LLM_Started(IntPtr LLMObject) {
return LLM_StartedStatic(LLMObject); }
439 public void LLM_Stop(IntPtr LLMObject) { LLM_StopStatic(LLMObject); }
440 public void LLM_SetTemplate(IntPtr LLMObject,
string chatTemplate) { LLM_SetTemplateStatic(LLMObject, chatTemplate); }
441 public void LLM_SetSSL(IntPtr LLMObject,
string SSLCert,
string SSLKey) { LLM_SetSSLStatic(LLMObject, SSLCert, SSLKey); }
442 public void LLM_Tokenize(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_TokenizeStatic(LLMObject, jsonData, stringWrapper); }
443 public void LLM_Detokenize(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_DetokenizeStatic(LLMObject, jsonData, stringWrapper); }
444 public void LLM_Embeddings(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_EmbeddingsStatic(LLMObject, jsonData, stringWrapper); }
445 public void LLM_LoraWeight(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_LoraWeightStatic(LLMObject, jsonData, stringWrapper); }
446 public void LLM_LoraList(IntPtr LLMObject, IntPtr stringWrapper) { LLM_LoraListStatic(LLMObject, stringWrapper); }
447 public void LLM_Completion(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_CompletionStatic(LLMObject, jsonData, stringWrapper); }
448 public void LLM_Slot(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper) { LLM_SlotStatic(LLMObject, jsonData, stringWrapper); }
449 public void LLM_Cancel(IntPtr LLMObject,
int idSlot) { LLM_CancelStatic(LLMObject, idSlot); }
450 public int LLM_Status(IntPtr LLMObject, IntPtr stringWrapper) {
return LLM_StatusStatic(LLMObject, stringWrapper); }
451 public IntPtr StringWrapper_Construct() {
return StringWrapper_ConstructStatic(); }
452 public void StringWrapper_Delete(IntPtr instance) { StringWrapper_DeleteStatic(instance); }
453 public int StringWrapper_GetStringSize(IntPtr instance) {
return StringWrapper_GetStringSizeStatic(instance); }
454 public void StringWrapper_GetString(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false) { StringWrapper_GetStringStatic(instance, buffer, bufferSize, clear); }
458 static bool has_avx_set =
false;
459 static readonly
object staticLock =
new object();
465 if (has_avx_set)
return;
466 string archCheckerPath = GetArchitectureCheckerPath();
467 if (archCheckerPath !=
null)
469 IntPtr archCheckerHandle = LibraryLoader.LoadLibrary(archCheckerPath);
470 if (archCheckerHandle == IntPtr.Zero)
472 LLMUnitySetup.LogError($
"Failed to load library {archCheckerPath}.");
478 has_avx = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx")();
479 has_avx2 = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx2")();
480 has_avx512 = LibraryLoader.GetSymbolDelegate<HasArchDelegate>(archCheckerHandle,
"has_avx512")();
481 LibraryLoader.FreeLibrary(archCheckerHandle);
485 LLMUnitySetup.LogError($
"{e.GetType()}: {e.Message}");
498 public LLMLib(
string arch)
500 foreach (
string dependency
in GetArchitectureDependencies(arch))
502 LLMUnitySetup.Log($
"Loading {dependency}");
503 dependencyHandles.Add(LibraryLoader.LoadLibrary(dependency));
506 libraryHandle = LibraryLoader.LoadLibrary(GetArchitecturePath(arch));
507 if (libraryHandle == IntPtr.Zero)
509 throw new Exception($
"Failed to load library {arch}.");
512 LLM_Construct = LibraryLoader.GetSymbolDelegate<LLM_ConstructDelegate>(libraryHandle,
"LLM_Construct");
513 LLM_Delete = LibraryLoader.GetSymbolDelegate<LLM_DeleteDelegate>(libraryHandle,
"LLM_Delete");
514 LLM_StartServer = LibraryLoader.GetSymbolDelegate<LLM_StartServerDelegate>(libraryHandle,
"LLM_StartServer");
515 LLM_StopServer = LibraryLoader.GetSymbolDelegate<LLM_StopServerDelegate>(libraryHandle,
"LLM_StopServer");
516 LLM_Start = LibraryLoader.GetSymbolDelegate<LLM_StartDelegate>(libraryHandle,
"LLM_Start");
517 LLM_Started = LibraryLoader.GetSymbolDelegate<LLM_StartedDelegate>(libraryHandle,
"LLM_Started");
518 LLM_Stop = LibraryLoader.GetSymbolDelegate<LLM_StopDelegate>(libraryHandle,
"LLM_Stop");
519 LLM_SetTemplate = LibraryLoader.GetSymbolDelegate<LLM_SetTemplateDelegate>(libraryHandle,
"LLM_SetTemplate");
520 LLM_SetSSL = LibraryLoader.GetSymbolDelegate<LLM_SetSSLDelegate>(libraryHandle,
"LLM_SetSSL");
521 LLM_Tokenize = LibraryLoader.GetSymbolDelegate<LLM_TokenizeDelegate>(libraryHandle,
"LLM_Tokenize");
522 LLM_Detokenize = LibraryLoader.GetSymbolDelegate<LLM_DetokenizeDelegate>(libraryHandle,
"LLM_Detokenize");
523 LLM_Embeddings = LibraryLoader.GetSymbolDelegate<LLM_EmbeddingsDelegate>(libraryHandle,
"LLM_Embeddings");
524 LLM_LoraWeight = LibraryLoader.GetSymbolDelegate<LLM_LoraWeightDelegate>(libraryHandle,
"LLM_Lora_Weight");
525 LLM_LoraList = LibraryLoader.GetSymbolDelegate<LLM_LoraListDelegate>(libraryHandle,
"LLM_Lora_List");
526 LLM_Completion = LibraryLoader.GetSymbolDelegate<LLM_CompletionDelegate>(libraryHandle,
"LLM_Completion");
527 LLM_Slot = LibraryLoader.GetSymbolDelegate<LLM_SlotDelegate>(libraryHandle,
"LLM_Slot");
528 LLM_Cancel = LibraryLoader.GetSymbolDelegate<LLM_CancelDelegate>(libraryHandle,
"LLM_Cancel");
529 LLM_Status = LibraryLoader.GetSymbolDelegate<LLM_StatusDelegate>(libraryHandle,
"LLM_Status");
530 StringWrapper_Construct = LibraryLoader.GetSymbolDelegate<StringWrapper_ConstructDelegate>(libraryHandle,
"StringWrapper_Construct");
531 StringWrapper_Delete = LibraryLoader.GetSymbolDelegate<StringWrapper_DeleteDelegate>(libraryHandle,
"StringWrapper_Delete");
532 StringWrapper_GetStringSize = LibraryLoader.GetSymbolDelegate<StringWrapper_GetStringSizeDelegate>(libraryHandle,
"StringWrapper_GetStringSize");
533 StringWrapper_GetString = LibraryLoader.GetSymbolDelegate<StringWrapper_GetStringDelegate>(libraryHandle,
"StringWrapper_GetString");
534 Logging = LibraryLoader.GetSymbolDelegate<LoggingDelegate>(libraryHandle,
"Logging");
535 StopLogging = LibraryLoader.GetSymbolDelegate<StopLoggingDelegate>(libraryHandle,
"StopLogging");
542 public static string GetArchitectureCheckerPath()
545 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
547 filename = $
"windows-archchecker/archchecker.dll";
549 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
551 filename = $
"linux-archchecker/libarchchecker.so";
557 return Path.Combine(LLMUnitySetup.libraryPath, filename);
565 public static List<string> GetArchitectureDependencies(
string arch)
567 List<string> dependencies =
new List<string>();
568 if (arch ==
"cuda-cu12.2.0-full")
570 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
572 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cudart64_12.dll"));
573 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cublasLt64_12.dll"));
574 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/cublas64_12.dll"));
576 }
else if (arch ==
"vulkan") {
577 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
579 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"windows-{arch}/vulkan-1.dll"));
581 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
583 dependencies.Add(Path.Combine(LLMUnitySetup.libraryPath, $
"linux-{arch}/libvulkan.so.1"));
594 public static string GetArchitecturePath(
string arch)
597 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer)
599 filename = $
"windows-{arch}/undreamai_windows-{arch}.dll";
601 else if (Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
603 filename = $
"linux-{arch}/libundreamai_linux-{arch}.so";
605 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer || Application.platform == RuntimePlatform.OSXServer)
607 filename = $
"macos-{arch}/libundreamai_macos-{arch}.dylib";
611 string error =
"Unknown OS";
612 LLMUnitySetup.LogError(error);
613 throw new Exception(error);
615 return Path.Combine(LLMUnitySetup.libraryPath, filename);
618 public delegate
bool HasArchDelegate();
619 public delegate
void LoggingDelegate(IntPtr stringWrapper);
620 public delegate
void StopLoggingDelegate();
621 public delegate IntPtr LLM_ConstructDelegate(
string command);
622 public delegate
void LLM_DeleteDelegate(IntPtr LLMObject);
623 public delegate
void LLM_StartServerDelegate(IntPtr LLMObject);
624 public delegate
void LLM_StopServerDelegate(IntPtr LLMObject);
625 public delegate
void LLM_StartDelegate(IntPtr LLMObject);
626 public delegate
bool LLM_StartedDelegate(IntPtr LLMObject);
627 public delegate
void LLM_StopDelegate(IntPtr LLMObject);
628 public delegate
void LLM_SetTemplateDelegate(IntPtr LLMObject,
string chatTemplate);
629 public delegate
void LLM_SetSSLDelegate(IntPtr LLMObject,
string SSLCert,
string SSLKey);
630 public delegate
void LLM_TokenizeDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
631 public delegate
void LLM_DetokenizeDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
632 public delegate
void LLM_EmbeddingsDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
633 public delegate
void LLM_LoraWeightDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
634 public delegate
void LLM_LoraListDelegate(IntPtr LLMObject, IntPtr stringWrapper);
635 public delegate
void LLM_CompletionDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
636 public delegate
void LLM_SlotDelegate(IntPtr LLMObject,
string jsonData, IntPtr stringWrapper);
637 public delegate
void LLM_CancelDelegate(IntPtr LLMObject,
int idSlot);
638 public delegate
int LLM_StatusDelegate(IntPtr LLMObject, IntPtr stringWrapper);
639 public delegate IntPtr StringWrapper_ConstructDelegate();
640 public delegate
void StringWrapper_DeleteDelegate(IntPtr instance);
641 public delegate
int StringWrapper_GetStringSizeDelegate(IntPtr instance);
642 public delegate
void StringWrapper_GetStringDelegate(IntPtr instance, IntPtr buffer,
int bufferSize,
bool clear =
false);
644 public LoggingDelegate Logging;
645 public StopLoggingDelegate StopLogging;
646 public LLM_ConstructDelegate LLM_Construct;
647 public LLM_DeleteDelegate LLM_Delete;
648 public LLM_StartServerDelegate LLM_StartServer;
649 public LLM_StopServerDelegate LLM_StopServer;
650 public LLM_StartDelegate LLM_Start;
651 public LLM_StartedDelegate LLM_Started;
652 public LLM_StopDelegate LLM_Stop;
653 public LLM_SetTemplateDelegate LLM_SetTemplate;
654 public LLM_SetSSLDelegate LLM_SetSSL;
655 public LLM_TokenizeDelegate LLM_Tokenize;
656 public LLM_DetokenizeDelegate LLM_Detokenize;
657 public LLM_CompletionDelegate LLM_Completion;
658 public LLM_EmbeddingsDelegate LLM_Embeddings;
659 public LLM_LoraWeightDelegate LLM_LoraWeight;
660 public LLM_LoraListDelegate LLM_LoraList;
661 public LLM_SlotDelegate LLM_Slot;
662 public LLM_CancelDelegate LLM_Cancel;
663 public LLM_StatusDelegate LLM_Status;
664 public StringWrapper_ConstructDelegate StringWrapper_Construct;
665 public StringWrapper_DeleteDelegate StringWrapper_Delete;
666 public StringWrapper_GetStringSizeDelegate StringWrapper_GetStringSize;
667 public StringWrapper_GetStringDelegate StringWrapper_GetString;
676 public static List<string> PossibleArchitectures(
bool gpu =
false)
678 List<string> architectures =
new List<string>();
679 if (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsServer ||
680 Application.platform == RuntimePlatform.LinuxEditor || Application.platform == RuntimePlatform.LinuxPlayer || Application.platform == RuntimePlatform.LinuxServer)
684 if (LLMUnitySetup.FullLlamaLib)
686 architectures.Add(
"cuda-cu12.2.0-full");
690 architectures.Add(
"cuda-cu12.2.0");
692 architectures.Add(
"hip");
693 architectures.Add(
"vulkan");
695 if (has_avx512) architectures.Add(
"avx512");
696 if (has_avx2) architectures.Add(
"avx2");
697 if (has_avx) architectures.Add(
"avx");
698 architectures.Add(
"noavx");
700 else if (Application.platform == RuntimePlatform.OSXEditor || Application.platform == RuntimePlatform.OSXPlayer)
702 string arch = RuntimeInformation.ProcessArchitecture.ToString().ToLower();
703 if (arch.Contains(
"arm"))
705 architectures.Add(
"arm64-acc");
706 architectures.Add(
"arm64-no_acc");
710 if (arch !=
"x86" && arch !=
"x64") LLMUnitySetup.LogWarning($
"Unknown architecture of processor {arch}! Falling back to x86_64");
711 architectures.Add(
"x64-acc");
712 architectures.Add(
"x64-no_acc");
715 else if (Application.platform == RuntimePlatform.Android)
717 architectures.Add(
"android");
719 else if (Application.platform == RuntimePlatform.IPhonePlayer)
721 architectures.Add(
"ios");
725 string error =
"Unknown OS";
726 LLMUnitySetup.LogError(error);
727 throw new Exception(error);
729 return architectures;
737 public string GetStringWrapperResult(IntPtr stringWrapper)
740 int bufferSize = StringWrapper_GetStringSize(stringWrapper);
743 IntPtr buffer = Marshal.AllocHGlobal(bufferSize);
746 StringWrapper_GetString(stringWrapper, buffer, bufferSize);
747 result = Marshal.PtrToStringAnsi(buffer);
751 Marshal.FreeHGlobal(buffer);
760 public void Destroy()
762 if (libraryHandle != IntPtr.Zero) LibraryLoader.FreeLibrary(libraryHandle);
763 foreach (IntPtr dependencyHandle
in dependencyHandles) LibraryLoader.FreeLibrary(dependencyHandle);