Mate-Engine/Assets/LLMUnity/Runtime/RAG/SimpleSearch.cs
shinyflvre 39a7b41d7d 1.4.0 Pre Release
**Changelog 1.4.0 – THE LOCAL AI Update**

**Disclaimer:**
The AI runs *entirely locally* and is designed to be environmentally and ethically responsible.
- It does **not** harm nature or exploit any artists.
- It has only **1.5 billion parameters**, making it a **very small model** by modern standards.
- It consumes as much GPU energy as watching a **1440p 60fps YouTube video**.
- It was **not trained on artist data**; it uses personal input and public Wikipedia datasets.
- It has its own personality, and I ensured it adheres to **ethical standards**.

---

### New Features

- Added **Qwen 2.5 1.5B LLM** to MateEngine!
  - Press **Middle Mouse Button** while hovering over the pet to open the chat window.
  - Runs fully locally on your GPU — no internet connection required.
  - Only uses GPU while processing prompts.
  - Note: This is a **lightweight model** and won’t handle complex tasks or coding. It’s just a small, fun feature!

- Added **Resize Button** – Quickly adjust app size for 1080p, 1440p, and 4K monitors.

- Added **VRM Information Panel** – Displays polygon count, VRM version, and bone status:
  - **Perfect** – Properly exported model.
  - **Failure** – Model has export issues; animations may break.

- Added **Options Submenu**.
- Added **Volume Sliders** – Independently control pet, effects, and menu volume.
- Added **Graphics Settings**.
- Added **Dance Trails** – Glowing effects on the pet’s hands during dance. Toggle on/off as desired.
- Improved **Music Source Selector** – You can now whitelist or add custom audio sources for dancing.
- Added **MateEngine Version Info** – View the current app version from the menu.
- Menu can now be opened with **M** key or **Right-Click**.
- Added full support for **VRM 1.x** and **VRM 0.x** models.
- Introduced **VRM Validator Tool** in Unity Editor – Great for content creators.

---

### Improvements & Fixes

- Major **Performance Optimizations**.
- Fixed a **GC Error** that could appear after 6–12 hours of continuous use.
- Improved **Hand Tracking** – Reduced stuttering in some animations.
- Added **Discord Rich Presence** integration.
- Added **Glowing Halo** for Steam users as exclusive DLC!
2025-04-08 19:16:19 +02:00

107 lines
4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO.Compression;
using UnityEngine;
namespace LLMUnity
{
/// @ingroup rag
/// <summary>
/// Class implementing a simple search that compares the enconding of the search query with all the search entries (brute-force).
/// </summary>
[DefaultExecutionOrder(-2)]
public class SimpleSearch : SearchMethod
{
/// \cond HIDE
protected SortedDictionary<int, float[]> embeddings = new SortedDictionary<int, float[]>();
protected Dictionary<int, List<(int, float)>> incrementalSearchCache = new Dictionary<int, List<(int, float)>>();
protected override void AddInternal(int key, float[] embedding)
{
embeddings[key] = embedding;
}
protected override void RemoveInternal(int key)
{
embeddings.Remove(key);
}
public override int IncrementalSearch(float[] embedding, string group = "")
{
int key = nextIncrementalSearchKey++;
List<(int, float)> sortedLists = new List<(int, float)>();
if (dataSplits.TryGetValue(group, out List<int> dataSplit))
{
if (dataSplit.Count >= 0)
{
float[][] embeddingsSplit = new float[dataSplit.Count][];
for (int i = 0; i < dataSplit.Count; i++) embeddingsSplit[i] = embeddings[dataSplit[i]];
float[] unsortedDistances = InverseDotProduct(embedding, embeddingsSplit);
sortedLists = dataSplit.Zip(unsortedDistances, (first, second) => (first, second))
.OrderBy(item => item.Item2)
.ToList();
}
}
incrementalSearchCache[key] = sortedLists;
return key;
}
public override ValueTuple<int[], float[], bool> IncrementalFetchKeys(int fetchKey, int k)
{
if (!incrementalSearchCache.ContainsKey(fetchKey)) throw new Exception($"There is no IncrementalSearch cached with this key: {fetchKey}");
bool completed;
List<(int, float)> sortedLists;
if (k == -1)
{
sortedLists = incrementalSearchCache[fetchKey];
completed = true;
}
else
{
int getK = Math.Min(k, incrementalSearchCache[fetchKey].Count);
sortedLists = incrementalSearchCache[fetchKey].GetRange(0, getK);
incrementalSearchCache[fetchKey].RemoveRange(0, getK);
completed = incrementalSearchCache[fetchKey].Count == 0;
}
if (completed) IncrementalSearchComplete(fetchKey);
int[] results = new int[sortedLists.Count];
float[] distances = new float[sortedLists.Count];
for (int i = 0; i < sortedLists.Count; i++)
{
results[i] = sortedLists[i].Item1;
distances[i] = sortedLists[i].Item2;
}
return (results.ToArray(), distances.ToArray(), completed);
}
public override void IncrementalSearchComplete(int fetchKey)
{
incrementalSearchCache.Remove(fetchKey);
}
protected override void ClearInternal()
{
embeddings.Clear();
incrementalSearchCache.Clear();
}
protected override void SaveInternal(ZipArchive archive)
{
ArchiveSaver.Save(archive, embeddings, GetSavePath("embeddings"));
ArchiveSaver.Save(archive, incrementalSearchCache, GetSavePath("incrementalSearchCache"));
}
protected override void LoadInternal(ZipArchive archive)
{
embeddings = ArchiveSaver.Load<SortedDictionary<int, float[]>>(archive, GetSavePath("embeddings"));
incrementalSearchCache = ArchiveSaver.Load<Dictionary<int, List<(int, float)>>>(archive, GetSavePath("incrementalSearchCache"));
}
/// \endcond
}
}