UnityGiles commited on
Commit
15df29b
·
1 Parent(s): 192d6ae

update to inference engine

Browse files
README.md CHANGED
@@ -2,47 +2,29 @@
2
  license: mit
3
  library_name: unity-sentis
4
  pipeline_tag: text-generation
 
 
5
  ---
6
 
 
7
 
8
- # Phi 1.5 Model in Unity Sentis (Version 1.5.0-pre.2)
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
- Alice smiled and replied, "That's a great question, Bob. We divide by 2 because the area of a triangle is half of the product of its base and height. It's a fundamental concept in geometry."
 
 
 
 
 
 
40
 
41
- Carol, who had been listening intently, added, "So, if we have a triangle with...
42
- ```
43
 
44
- ## Unity Sentis
45
- Unity Sentis is the inference engine which runs on Unity 2023. More can be found about it [here](https://unity.com/products/sentis)
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.Sentis;
5
- using System.IO;
6
  using System.Text;
7
- using FF = Unity.Sentis.Functional;
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
- //Drop the tinystories.sentis or onnx file on here if using an asset:
30
- //public ModelAsset asset;
 
 
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
- IWorker engine;
49
 
50
- int currentToken = 0;
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 = false;
58
-
59
 
60
  //stop after this many tokens
61
  const int stopAfter = 100;
62
 
63
- int totalTokens = 0;
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(Path.Join(Application.streamingAssetsPath , "phi15.sentis"));
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
- engine = WorkerFactory.CreateWorker(backend, model2);
 
 
 
 
 
 
 
89
 
90
  DecodePrompt(outputString);
91
 
@@ -103,15 +80,12 @@ public class RunPhi15: MonoBehaviour
103
 
104
  void RunInference()
105
  {
106
- using var tokensSoFar = new TensorInt(new TensorShape(1, maxTokens), outputTokens);
107
- using var index = new TensorInt(currentToken);
108
-
109
- engine.Execute(new Dictionary<string, Tensor> { {"input_0", tokensSoFar }, { "input_1", index }});
110
 
111
- var probs = engine.PeekOutput() as TensorInt;
112
- //Debug.Log(probs.shape);
113
 
114
- probs.CompleteOperationsAndDownload();
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 = File.ReadAllText(Path.Join(Application.streamingAssetsPath , "vocab.json"));
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 = File.ReadAllLines(Path.Join(Application.streamingAssetsPath , "merges.txt"));
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 += ((int)letter <= 256) ? letter :
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[(int)letter];
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
- private void OnDestroy()
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