Commit
·
15df29b
1
Parent(s):
192d6ae
update to inference engine
Browse files- README.md +15 -33
- RunPhi15.cs +35 -64
- merges.txt → data/merges.txt +0 -0
- vocab.json → data/vocab.json +0 -0
- info.js +0 -6
- info.json +15 -0
- phi15.sentis → models/phi15.sentis +0 -0
README.md
CHANGED
@@ -2,47 +2,29 @@
|
|
2 |
license: mit
|
3 |
library_name: unity-sentis
|
4 |
pipeline_tag: text-generation
|
|
|
|
|
5 |
---
|
6 |
|
|
|
7 |
|
8 |
-
|
9 |
-
*Version 1.3.0 Sentis files are not compatible with Sentis 1.5.0 and need to be recreated/downloaded
|
10 |
-
|
11 |
-
This is the [Microsoft Phi 1.5](https://huggingface.co/microsoft/phi-1_5) model checked to run on Unity 2023. Phi 1.5 is a Large Language Model that was trained on synthesized data. Please see their page for more information about the model and license.
|
12 |
-
The model has 1.3 billion parameters.
|
13 |
-
|
14 |
|
15 |
## How to Use
|
16 |
-
* Create a new scene in Unity 2023
|
17 |
-
* Install `com.unity.sentis` version `1.5.0-pre.2` and `com.unity.nuget.newtonsoft-json` packages
|
18 |
-
* Add the RunPhi15.cs file to the Main Camera
|
19 |
-
* Put `phi15.sentis`, `vocab.json` and `merges.txt` in the Assets/StreamingAssets folder
|
20 |
-
* Adjust some of the variables such as the `outputText` string to set the prompt
|
21 |
-
* Press run
|
22 |
-
* The output will appear in the console window (after some time. You may want to open the RAM inspector to see what is going on.)
|
23 |
-
|
24 |
-
## Information
|
25 |
-
This is the float32 version so it requires a lot of RAM (16GB) and VRAM (8GB). With less RAM it may take a long time to load. In the future we may add the float16 or uint8 quantized versions. This version also doesn't use caching of previous iterations so it is not the optimum speed but the implementation is simpler.
|
26 |
-
|
27 |
-
## Example Input
|
28 |
-
```
|
29 |
-
Once upon a time, there were three
|
30 |
-
```
|
31 |
-
## Example Output
|
32 |
-
```
|
33 |
-
Once upon a time, there were three friends named Alice, Bob, and Carol. They were all passionate about mathematics and loved solving complex problems together. One day, they came across a challenging problem that required them to find the area of a triangle using the Pythagorean theorem.
|
34 |
-
|
35 |
-
Alice, being the most experienced in geometry, took the lead and explained the steps to her friends. "To find the area of a triangle, we need to multiply the base by the height and divide the result by 2," she said confidently.
|
36 |
-
|
37 |
-
Bob, who was always curious, asked, "But why do we divide the result by 2? Can't we just multiply the base and height?"
|
38 |
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
-
|
42 |
-
|
43 |
|
44 |
-
##
|
45 |
-
|
46 |
|
47 |
## Disclaimer
|
48 |
Like any LLM, this model has the possibility to generate undesirable or untruthful text. Use at your discretion.
|
|
|
2 |
license: mit
|
3 |
library_name: unity-sentis
|
4 |
pipeline_tag: text-generation
|
5 |
+
tags:
|
6 |
+
- unity-inference-engine
|
7 |
---
|
8 |
|
9 |
+
# Phi 1.5 in Unity 6 with Inference Engine
|
10 |
|
11 |
+
This is the [Microsoft Phi 1.5](https://huggingface.co/microsoft/phi-1_5) running in Unity 6 with Inference Engine. Phi 1.5 is a Large Language Model trained on synthesized data. The model has 1.3 billion parameters.
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
## How to Use
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
+
* Create a new scene in Unity 6;
|
16 |
+
* Install `com.unity.ai.inference` from the package manager;
|
17 |
+
* Install `com.unity.nuget.newtonsoft-json` from the package manager;
|
18 |
+
* Add the `RunPhi15.cs` script to the Main Camera;
|
19 |
+
* Drag the `phi15.sentis` asset from the `models` folder into the `Model Asset` field;
|
20 |
+
* Drag the `vocab.json` asset from the `data` folder into the `Vocab Asset` field;
|
21 |
+
* Drag the `merges.txt` asset from the `data` folder into the `Merges Asset` field;
|
22 |
|
23 |
+
## Preview
|
24 |
+
Enter play mode. If working correctly the predicted text will be logged to the console.
|
25 |
|
26 |
+
## Inference Engine
|
27 |
+
Inference Engine is a neural network inference library for Unity. Find out more [here](https://docs.unity3d.com/Packages/com.unity.ai.inference@latest).
|
28 |
|
29 |
## Disclaimer
|
30 |
Like any LLM, this model has the possibility to generate undesirable or untruthful text. Use at your discretion.
|
RunPhi15.cs
CHANGED
@@ -1,33 +1,15 @@
|
|
1 |
-
using System.Collections;
|
2 |
using System.Collections.Generic;
|
3 |
using UnityEngine;
|
4 |
-
using Unity.
|
5 |
-
using System.IO;
|
6 |
using System.Text;
|
7 |
-
using FF = Unity.
|
8 |
-
|
9 |
-
|
10 |
-
* Phi1.5 Inference Code
|
11 |
-
* ===========================
|
12 |
-
*
|
13 |
-
* Put this script on the Main Camera
|
14 |
-
*
|
15 |
-
* In Assets/StreamingAssets put:
|
16 |
-
*
|
17 |
-
* phi15.sentis (or put in asset folder)
|
18 |
-
* vocab.json
|
19 |
-
* merges.txt
|
20 |
-
*
|
21 |
-
* Install package com.unity.nuget.newtonsoft-json from packagemanger
|
22 |
-
* Install package com.unity.sentis
|
23 |
-
*
|
24 |
-
*/
|
25 |
-
|
26 |
-
|
27 |
-
public class RunPhi15: MonoBehaviour
|
28 |
{
|
29 |
-
|
30 |
-
|
|
|
|
|
31 |
const BackendType backend = BackendType.GPUCompute;
|
32 |
|
33 |
//string outputString = "Once upon a time, there were three bears";
|
@@ -45,22 +27,21 @@ public class RunPhi15: MonoBehaviour
|
|
45 |
//Store the vocabulary
|
46 |
string[] tokens;
|
47 |
|
48 |
-
|
49 |
|
50 |
-
int currentToken
|
51 |
int[] outputTokens = new int[maxTokens];
|
52 |
|
53 |
// Used for special character decoding
|
54 |
int[] whiteSpaceCharacters = new int[256];
|
55 |
int[] encodedCharacters = new int[256];
|
56 |
|
57 |
-
bool runInference
|
58 |
-
|
59 |
|
60 |
//stop after this many tokens
|
61 |
const int stopAfter = 100;
|
62 |
|
63 |
-
int totalTokens
|
64 |
|
65 |
string[] merges;
|
66 |
Dictionary<string, int> vocab;
|
@@ -71,21 +52,17 @@ public class RunPhi15: MonoBehaviour
|
|
71 |
|
72 |
LoadVocabulary();
|
73 |
|
74 |
-
var model1 = ModelLoader.Load(
|
75 |
-
|
76 |
-
int outputIndex = model1.outputs.Count - 1;
|
77 |
-
//var model1 = ModelLoader.Load(asset);
|
78 |
//Create a new model to select the random token:
|
79 |
-
var model2 = FF.Compile(
|
80 |
-
(input, currentToken) =>
|
81 |
-
{
|
82 |
-
var row = FF.Select(model1.Forward(input)[outputIndex], 1, currentToken);
|
83 |
-
return FF.Multinomial(predictability * row, 1);
|
84 |
-
},
|
85 |
-
(model1.inputs[0], InputDef.Int(new TensorShape()))
|
86 |
-
);
|
87 |
|
88 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
|
90 |
DecodePrompt(outputString);
|
91 |
|
@@ -103,15 +80,12 @@ public class RunPhi15: MonoBehaviour
|
|
103 |
|
104 |
void RunInference()
|
105 |
{
|
106 |
-
using var tokensSoFar = new
|
107 |
-
using var index = new
|
108 |
-
|
109 |
-
engine.Execute(new Dictionary<string, Tensor> { {"input_0", tokensSoFar }, { "input_1", index }});
|
110 |
|
111 |
-
|
112 |
-
//Debug.Log(probs.shape);
|
113 |
|
114 |
-
probs.
|
115 |
|
116 |
int ID = probs[0];
|
117 |
|
@@ -137,23 +111,22 @@ public class RunPhi15: MonoBehaviour
|
|
137 |
else outputString += GetUnicodeText(tokens[ID]);
|
138 |
|
139 |
Debug.Log(outputString);
|
140 |
-
|
141 |
}
|
142 |
|
143 |
void DecodePrompt(string text)
|
144 |
{
|
145 |
var inputTokens = GetTokens(text);
|
146 |
|
147 |
-
for(int i = 0; i < inputTokens.Count; i++)
|
148 |
{
|
149 |
outputTokens[i] = inputTokens[i];
|
150 |
}
|
151 |
currentToken = inputTokens.Count - 1;
|
152 |
}
|
153 |
-
|
154 |
void LoadVocabulary()
|
155 |
{
|
156 |
-
var jsonText =
|
157 |
vocab = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(jsonText);
|
158 |
tokens = new string[vocab.Count];
|
159 |
foreach (var item in vocab)
|
@@ -161,7 +134,7 @@ public class RunPhi15: MonoBehaviour
|
|
161 |
tokens[item.Value] = item.Key;
|
162 |
}
|
163 |
|
164 |
-
merges =
|
165 |
}
|
166 |
|
167 |
// Translates encoded special characters to Unicode
|
@@ -181,8 +154,7 @@ public class RunPhi15: MonoBehaviour
|
|
181 |
string outText = "";
|
182 |
foreach (char letter in text)
|
183 |
{
|
184 |
-
outText += (
|
185 |
-
(char)whiteSpaceCharacters[(int)(letter - 256)];
|
186 |
}
|
187 |
return outText;
|
188 |
}
|
@@ -192,7 +164,7 @@ public class RunPhi15: MonoBehaviour
|
|
192 |
string outText = "";
|
193 |
foreach (char letter in text)
|
194 |
{
|
195 |
-
outText += (char)encodedCharacters[
|
196 |
}
|
197 |
return outText;
|
198 |
}
|
@@ -222,7 +194,7 @@ public class RunPhi15: MonoBehaviour
|
|
222 |
|
223 |
// Start with a list of single characters
|
224 |
var inputTokens = new List<string>();
|
225 |
-
foreach(var letter in text)
|
226 |
{
|
227 |
inputTokens.Add(letter.ToString());
|
228 |
}
|
@@ -231,7 +203,7 @@ public class RunPhi15: MonoBehaviour
|
|
231 |
|
232 |
//Find the ids of the words in the vocab
|
233 |
var ids = new List<int>();
|
234 |
-
foreach(var token in inputTokens)
|
235 |
{
|
236 |
if (vocab.TryGetValue(token, out int id))
|
237 |
{
|
@@ -244,7 +216,7 @@ public class RunPhi15: MonoBehaviour
|
|
244 |
|
245 |
void ApplyMerges(List<string> inputTokens)
|
246 |
{
|
247 |
-
foreach(var merge in merges)
|
248 |
{
|
249 |
string[] pair = merge.Split(' ');
|
250 |
int n = 0;
|
@@ -261,9 +233,8 @@ public class RunPhi15: MonoBehaviour
|
|
261 |
}
|
262 |
}
|
263 |
|
264 |
-
|
265 |
{
|
266 |
engine?.Dispose();
|
267 |
}
|
268 |
-
|
269 |
}
|
|
|
|
|
1 |
using System.Collections.Generic;
|
2 |
using UnityEngine;
|
3 |
+
using Unity.InferenceEngine;
|
|
|
4 |
using System.Text;
|
5 |
+
using FF = Unity.InferenceEngine.Functional;
|
6 |
+
|
7 |
+
public class RunPhi15 : MonoBehaviour
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
{
|
9 |
+
public ModelAsset modelAsset;
|
10 |
+
public TextAsset vocabAsset;
|
11 |
+
public TextAsset mergesAsset;
|
12 |
+
|
13 |
const BackendType backend = BackendType.GPUCompute;
|
14 |
|
15 |
//string outputString = "Once upon a time, there were three bears";
|
|
|
27 |
//Store the vocabulary
|
28 |
string[] tokens;
|
29 |
|
30 |
+
Worker engine;
|
31 |
|
32 |
+
int currentToken;
|
33 |
int[] outputTokens = new int[maxTokens];
|
34 |
|
35 |
// Used for special character decoding
|
36 |
int[] whiteSpaceCharacters = new int[256];
|
37 |
int[] encodedCharacters = new int[256];
|
38 |
|
39 |
+
bool runInference;
|
|
|
40 |
|
41 |
//stop after this many tokens
|
42 |
const int stopAfter = 100;
|
43 |
|
44 |
+
int totalTokens;
|
45 |
|
46 |
string[] merges;
|
47 |
Dictionary<string, int> vocab;
|
|
|
52 |
|
53 |
LoadVocabulary();
|
54 |
|
55 |
+
var model1 = ModelLoader.Load(modelAsset);
|
|
|
|
|
|
|
56 |
//Create a new model to select the random token:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
+
var graph = new FunctionalGraph();
|
59 |
+
var input = graph.AddInput(model1, 0);
|
60 |
+
var currentTokenInput = graph.AddInput<int>(new TensorShape(), "currentToken");
|
61 |
+
var row = FF.Select(Functional.Forward(model1, input)[^1], 1, currentTokenInput);
|
62 |
+
var output = FF.Multinomial(predictability * row, 1);
|
63 |
+
var model2 = graph.Compile(output);
|
64 |
+
|
65 |
+
engine = new Worker(model2, backend);
|
66 |
|
67 |
DecodePrompt(outputString);
|
68 |
|
|
|
80 |
|
81 |
void RunInference()
|
82 |
{
|
83 |
+
using var tokensSoFar = new Tensor<int>(new TensorShape(1, maxTokens), outputTokens);
|
84 |
+
using var index = new Tensor<int>(new TensorShape(), new[] { currentToken });
|
|
|
|
|
85 |
|
86 |
+
engine.Schedule(tokensSoFar, index);
|
|
|
87 |
|
88 |
+
using var probs = (engine.PeekOutput() as Tensor<int>).ReadbackAndClone();
|
89 |
|
90 |
int ID = probs[0];
|
91 |
|
|
|
111 |
else outputString += GetUnicodeText(tokens[ID]);
|
112 |
|
113 |
Debug.Log(outputString);
|
|
|
114 |
}
|
115 |
|
116 |
void DecodePrompt(string text)
|
117 |
{
|
118 |
var inputTokens = GetTokens(text);
|
119 |
|
120 |
+
for (int i = 0; i < inputTokens.Count; i++)
|
121 |
{
|
122 |
outputTokens[i] = inputTokens[i];
|
123 |
}
|
124 |
currentToken = inputTokens.Count - 1;
|
125 |
}
|
126 |
+
|
127 |
void LoadVocabulary()
|
128 |
{
|
129 |
+
var jsonText = vocabAsset.text;
|
130 |
vocab = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, int>>(jsonText);
|
131 |
tokens = new string[vocab.Count];
|
132 |
foreach (var item in vocab)
|
|
|
134 |
tokens[item.Value] = item.Key;
|
135 |
}
|
136 |
|
137 |
+
merges = mergesAsset.text.Split("\r\n");
|
138 |
}
|
139 |
|
140 |
// Translates encoded special characters to Unicode
|
|
|
154 |
string outText = "";
|
155 |
foreach (char letter in text)
|
156 |
{
|
157 |
+
outText += (letter <= 256) ? letter : (char)whiteSpaceCharacters[letter - 256];
|
|
|
158 |
}
|
159 |
return outText;
|
160 |
}
|
|
|
164 |
string outText = "";
|
165 |
foreach (char letter in text)
|
166 |
{
|
167 |
+
outText += (char)encodedCharacters[letter];
|
168 |
}
|
169 |
return outText;
|
170 |
}
|
|
|
194 |
|
195 |
// Start with a list of single characters
|
196 |
var inputTokens = new List<string>();
|
197 |
+
foreach (var letter in text)
|
198 |
{
|
199 |
inputTokens.Add(letter.ToString());
|
200 |
}
|
|
|
203 |
|
204 |
//Find the ids of the words in the vocab
|
205 |
var ids = new List<int>();
|
206 |
+
foreach (var token in inputTokens)
|
207 |
{
|
208 |
if (vocab.TryGetValue(token, out int id))
|
209 |
{
|
|
|
216 |
|
217 |
void ApplyMerges(List<string> inputTokens)
|
218 |
{
|
219 |
+
foreach (var merge in merges)
|
220 |
{
|
221 |
string[] pair = merge.Split(' ');
|
222 |
int n = 0;
|
|
|
233 |
}
|
234 |
}
|
235 |
|
236 |
+
void OnDestroy()
|
237 |
{
|
238 |
engine?.Dispose();
|
239 |
}
|
|
|
240 |
}
|
merges.txt → data/merges.txt
RENAMED
File without changes
|
vocab.json → data/vocab.json
RENAMED
File without changes
|
info.js
DELETED
@@ -1,6 +0,0 @@
|
|
1 |
-
{
|
2 |
-
"version" : [
|
3 |
-
"1.3.0-pre.3"
|
4 |
-
]
|
5 |
-
|
6 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
info.json
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"code": [
|
3 |
+
"RunPhi15.cs"
|
4 |
+
],
|
5 |
+
"models": [
|
6 |
+
"models/phi15.sentis"
|
7 |
+
],
|
8 |
+
"data": [
|
9 |
+
"data/vocab.json",
|
10 |
+
"data/merges.txt"
|
11 |
+
],
|
12 |
+
"version": [
|
13 |
+
"2.2.0"
|
14 |
+
]
|
15 |
+
}
|
phi15.sentis → models/phi15.sentis
RENAMED
File without changes
|