TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

Unity Barracudaでdlshogiのモデルを推論する その2(推論速度)

前回、Unity Barracudaでdlshogiのモデルを推論できることを確認した。

今回は、dlshogiで使用しているTensorRTと、推論速度を比較した。

モデルは、15ブロック224フィルタのdlshogiのモデルを使用した。
前回の記事で書いた通り、そのままではBarracudaでdlshogiのモデルが使用できないため、torch.flattenとviewに変更してonnxを作成し直している。

測定条件

floodgateの棋譜からサンプリングした64000局面をバッチサイズ128で推論した際の時間を比較した。

測定コード

Barracudaの計測は、Unity側でsfenで局面の一覧を読み込んで入力特徴量もC#側で作成できるようにした。
計測する範囲は、入力特徴量作成は含めず、推論部分のみにしている。

    void Test3()
    {
        Model runtimeModel = ModelLoader.Load(modelAsset, true);

        var worker = WorkerFactory.CreateWorker(WorkerFactory.Type.Compute, runtimeModel);

        int batchsize = 128;
        float[] inputData1 = new float[(int)CSharpShogi.Color.ColorNum * Features.MaxFeatures1Num * (int)Square.SquareNum * batchsize];
        float[] inputData2 = new float[Features.MaxFeatures2Num * (int)Square.SquareNum * batchsize];


        Position pos = new Position(Position.DefaultStartPositionSFEN);

        var sw = new System.Diagnostics.Stopwatch();

        TextAsset textAsset = Resources.Load<TextAsset>("floodgate.sfen");
        int i = 0;
        foreach (var sfen in textAsset.text.Split("\n"))
        {
            pos.Set(sfen);
            Features.MakeInputFeatures(pos, inputData1, inputData2, i);

            if (++i == batchsize)
            {
                sw.Start();

                Tensor inputTensor1 = new Tensor(batchsize, 9, 9, 62, inputData1);
                Tensor inputTensor2 = new Tensor(batchsize, 9, 9, 57, inputData2);

                worker.Execute(new Dictionary<string, Tensor> { { "input1", inputTensor1 }, { "input2", inputTensor2 } });

                Tensor outputTensorPolicy = worker.PeekOutput("output_policy");
                Tensor outputTensorValue = worker.PeekOutput("output_value");
                float[] outputPolicy = outputTensorPolicy.data.Download(new TensorShape(2187 * batchsize));
                float[] outputValue = outputTensorValue.data.Download(new TensorShape(batchsize));

                inputTensor1.Dispose();
                inputTensor2.Dispose();
                outputTensorPolicy.Dispose();
                outputTensorValue.Dispose();

                sw.Stop();

                Array.Clear(inputData1, 0, inputData1.Length);
                Array.Clear(inputData2, 0, inputData2.Length);

                i = 0;
            }
        }

        worker.Dispose();

        text1.text = sw.ElapsedMilliseconds.ToString();
    }

測定結果

時間(ms)
TensorRT 1687
Barracuda 20409

Barracudaの方が12倍遅いという結果になった。

TensorRTと比べると速度はでないようだ。

以前に測定したcuDNN(32bit)とTensorRT(16bit)の比較では、3.3倍程度だったので、cuDNNと比べてもかなり遅くなっている。

以前に測定したONNXRuntime(DirectML)とTensorRTの比較では、4.7倍程度だったので、ONNXRuntime(DirectML)と比べても遅い。

Barracudaは、入力TensorがNHWCになっているので、CPUやスマートフォン向けに最適化されているのかもしれない。

まとめ

Barracudaの推論速度をTensorRTと比較した。
dlsohgiの15ブロック224フィルタのモデルの推論では、Barracudaが12倍遅いという結果であった。
また、DirectMLを使用したOnnxRuntimeと比較しても遅いことがわかった。
WindowsAMDGPUにも対応したい場合は、OnnxRuntimeを使用した方がよい。
Barracudaを使う場面は、スマートフォン向けになりそうだ。