File size: 3,262 Bytes
74ab0d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using UnityEngine;

namespace Sky.OnnxRuntime.Samples
{
    /// <summary>
    /// Demonstrates ONNX Runtime Extensions custom operators. Extensions add
    /// operators for text/vision/audio pre- and post-processing (tokenizers,
    /// string ops, image decoders, …) that are not part of the base ONNX opset.
    ///
    /// This sample enables them with a single call —
    /// <see cref="SessionOptions.RegisterOrtExtensions"/> — and then runs a tiny
    /// embedded model that uses the <c>StringUpper</c> custom op
    /// (domain <c>ai.onnx.contrib</c>) to upper-case string tensors. No external
    /// model file is required.
    /// </summary>
    public sealed class ExtensionsSample : MonoBehaviour
    {
        // A 139-byte ONNX model with a single node:
        //   text_out = StringUpper(text_in)   in domain "ai.onnx.contrib"
        // Both tensors are 1-D string tensors.
        private const string ModelBase64 =
            "CAk6bAoxCgd0ZXh0X2luEgh0ZXh0X291dCILU3RyaW5nVXBwZXI6D2FpLm9ubnguY29udHJpYhIMc3RyaW5nX3VwcGVyWhMKB3RleHRfaW4SCAoGCAgSAgoAYhQKCHRleHRfb3V0EggKBggIEgIKAEIECgAQDUITCg9haS5vbm54LmNvbnRyaWIQAQ==";

        [SerializeField]
        private string[] _inputs = { "hello unity", "OnnxRuntime" };

        private void Start()
        {
            RunStringUpper();
        }

        /// <summary>Runs the embedded StringUpper model and logs the output.</summary>
        public void RunStringUpper()
        {
            try
            {
                byte[] modelBytes = Convert.FromBase64String(ModelBase64);

                using var options = new SessionOptions();

                // Registers all ONNX Runtime Extensions custom ops with this session.
                // The extensions native library is shipped with this package.
                options.RegisterOrtExtensions();

                using var session = new InferenceSession(modelBytes, options);

                var inputTensor = new DenseTensor<string>(_inputs, new int[] { _inputs.Length });
                var inputs = new List<NamedOnnxValue>
                {
                    NamedOnnxValue.CreateFromTensor("text_in", inputTensor)
                };

                using var results = session.Run(inputs);
                string[] output = results.First().AsTensor<string>().ToArray();

                Debug.Log($"[ORT Extensions] input  = [{string.Join(", ", _inputs)}]");
                Debug.Log($"[ORT Extensions] output = [{string.Join(", ", output)}]");

                bool ok = output.Zip(_inputs, (o, i) => o == i.ToUpperInvariant()).All(x => x);
                if (ok)
                    Debug.Log("[ORT Extensions] StringUpper custom op succeeded ✅");
                else
                    Debug.LogError("[ORT Extensions] Unexpected output ❌");
            }
            catch (Exception e)
            {
                Debug.LogError(
                    "[ORT Extensions] Failed to run the extensions custom op. Make sure the " +
                    "ONNX Runtime Extensions native library is present for this platform.\n" + e);
            }
        }
    }
}