Tensorflow: Tensorflow lite gpu mendelegasikan inferensi menggunakan opengl dan SSBO di android

Dibuat pada 3 Mar 2019  ·  102Komentar  ·  Sumber: tensorflow/tensorflow

Sistem Informasi

  • Apakah saya telah menulis kode khusus (sebagai lawan menggunakan skrip contoh stok yang disediakan di TensorFlow):
    Ya, kode inferensi yang dimodifikasi dari tflite gpu mendelegasikan sampel android dengan kode tambahan dari https://www.tensorflow.org/lite/performance/gpu_advanced#android_2.
  • Platform dan Distribusi OS: Android 8.0.0
  • Perangkat seluler: OnePlus 3
  • Versi TensorFlow: 12.0

Jelaskan perilaku saat ini
Dokumentasi delegasi gpu tensorflow lite telah memberikan kode contoh untuk menjalankan inferensi tflite secara efisien di android, menghindari penyalinan memori CPU_GPU dengan bantuan opengl dan SSBO dalam konteks egl. Namun, metode ini tampaknya tidak memberikan peningkatan kinerja apa pun; melainkan menurunkan kinerja inferensi dalam hal kecepatan. Dokumentasi menyebutkan metode - 'interpreter.runInference (null, outputArray)' untuk menjalankan inferensi dalam kasus ini. Apakah metode ini sama dengan metode run dasar yaitu interpreter.run (inputTensor , outputTensor). (Sepertinya tidak ada metode dalam api saat ini yang disebut 'interpreter.runInference'). Apakah metode yang disarankan saat ini didukung dalam api delegasi gpu eksperimental (yaitu mengakses gambar input dari opengl ssbo secara langsung untuk menjalankan inferensi)? Bagaimana kita bisa memastikan bahwa model tersebut mengambil masukan dari SSBO ini dalam memori GPU?

* Perilaku yang diharapkan *
Inferensi tflite yang menggunakan opengl ssbo seharusnya lebih cepat daripada inferensi delegasi gpu dasar, di mana data disalin setiap saat dari cpu ke gpu.

Info / log lainnya
Kami mengukur waktu untuk metode 'tflite.run' di studio android. Input menggunakan format ByteBuffer yang direkomendasikan.

Kesalahan: Tidak dapat menyelesaikan metode runInference (null,?)

lite bug

Komentar yang paling membantu

Belum diumumkan secara resmi, tetapi FYI: kode GPU sekarang terlihat di:

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/delegates/gpu

jika Anda membutuhkan kode untuk mendapatkan pemahaman yang lebih baik tentang apa yang terjadi.

Semua 102 komentar

@ anilsyan7

Terima kasih telah mencoba delegasi GPU.

Dapatkah Anda memberikan lebih banyak konteks dalam hal waktu, misalnya berapa milidetik / detik sebelum dan sesudahnya?

Jenis jaringan apa yang Anda gunakan? Secara khusus, apakah semua operasi didukung?

Sudahkah Anda menulis kode shader khusus untuk menyalin tekstur kamera ke SSBO, atau apakah Anda hanya membuang memori CPU ke SSBO sendiri? Jika yang pertama, Anda melakukan hal-hal dengan benar dan seharusnya menjadi lebih cepat. Jika yang terakhir, itu hanya akan menjadi lebih lambat.

Model: Mirip dengan Model Segmentasi TF-Lite Resmi (grafik inferensi model dilampirkan sebagai gambar). Tiga node tambahan terakhir tampaknya tidak didukung oleh delegasi GPU. Ukuran gambar input adalah 129 * 129.

Telepon: OnePlus 3, GPU: Adreno 530

Waktu: -
Inferensi CPU: 60-70 ms
GPU Inferensi: 40-50 ms
GPU Inferensi (SSBO): 80-90 ms

yaitu Waktu untuk menjalankan metode 'interpreter.run ()'.

Berikut adalah metode yang kami gunakan untuk menyalin tekstur kamera ke SSBO: -

//Initialise SSBO
public int[] initializeShaderBuffer(){
    android.opengl.EGLContext eglContext = eglGetCurrentContext();
    int[] id = new int[1];
    GLES31.glGenBuffers(id.length, id, 0);
    GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, id[0]);
    GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, mWidth * mHeight, null, GLES31.GL_STREAM_COPY);
    GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);// unbind
    return id;
}
int inputSsboId = initializeShaderBuffer()[0];

 //After that every time a frame is available OR in onDraFrame(), call 
fillSsboWithCameraImageTexture(inputSsboId,data);

//(Note: Data is Nothing but Camera Frame ByteBuffer)

// Fill Ssbo With CameraImageTexture 

private int fillSsboWithCameraImageTexture(int inputSsboId,ByteBuffer cameraFramme) {

    GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, mWidth * mHeight, cameraFramme, GLES31.GL_STREAM_COPY);
    return inputSsboId;

}

129_80k_dm05

Dapatkah metode 'Interpreter.run ()' yang sama menangani input normal dari CPU dan SSBO? Atau adakah opsi / fungsi lain untuk menjalankan inferensi dalam kasus ini?

@ anilsyan7

Maaf atas tanggapan yang tertunda. Untuk beberapa alasan, saya baru saja mendapatkan ini di kotak masuk saya> _ <

Pertanyaan cepat tentang: kode Anda:

Bukankah harus begitu

GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, 3 * mWidth * mHeight, null, GLES31.GL_STREAM_COPY);

?

Juga, apakah Anda memiliki kemewahan untuk membuat input SSBO dengan bentuk 1x129x129x4? Kemudian Anda bisa menghilangkan satu memcpy yang tersembunyi di dalamnya.

Dari grafik yang Anda bagikan (btw, visualisasi yang bagus; hargai itu), sepertinya semuanya akan ditangani hingga ResizeBilinear terakhir. Bentuknya juga tidak terlalu buruk (129x129x2), dari segi terlalu banyak saluran, dll. Jadi saya tidak berharap ada penurunan.

Apakah Anda benar menelepon BindGlBufferToTensor sebelum ModifyGraphWithDelegate ? Bisakah Anda membagikan kode shader yang mengubah tekstur Anda menjadi SSBO? Saya melakukan sesuatu seperti:

   #version 310 es
   layout(local_size_x = 16, local_size_y = 16) in;
   layout(binding = 0) uniform sampler2D input_texture;
   layout(std430) buffer;
   layout(binding = 1) buffer Output { float elements[]; } output_data;
   void main() {
     ivec2 gid = ivec2(gl_GlobalInvocationID.xy);
     if (gid.x >= 224 || gid.y >= 224) return;
     vec3 pixel = texelFetch(input_texture, gid, 0).xyz;
     int linear_index = 3 * (gid.y * 224 + gid.x);
     output_data.elements[linear_index + 0] = pixel.x;
     output_data.elements[linear_index + 1] = pixel.y;
     output_data.elements[linear_index + 2] = pixel.z;
   }

untuk MobileNet. Mungkin tidak dapat diterapkan secara langsung, tetapi Anda secara kasar mendapatkan idenya ...

Belum diumumkan secara resmi, tetapi FYI: kode GPU sekarang terlihat di:

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/delegates/gpu

jika Anda membutuhkan kode untuk mendapatkan pemahaman yang lebih baik tentang apa yang terjadi.

Hai @impjay ,
Bisakah Anda membagikan aplikasi klasifikasi sampel menggunakan ssbo atau setidaknya kode terkait OpenGL?
Kami menggunakan kode shader berikut berdasarkan masukan Anda. Tetapi kami mengalami beberapa kesalahan terkait dengan versi shader, yang tidak dapat kami selesaikan sebagai pemula.

#version 310 es
layout(local_size_x = 16, local_size_y = 16) in;
layout(binding = 0) uniform sampler2D u_Texture0;
layout(std430) buffer;
layout(binding = 1) buffer Output { float elements[]; } output_data;
void main() {
    ivec2 gid = ivec2(gl_GlobalInvocationID.xy);
    if (gid.x >= 257 || gid.y >= 257) return;
    vec3 pixel = texelFetch(u_Texture0, gid, 0).xyz;
    int linear_index = 3 * (gid.y * 257 + gid.x);
    output_data.elements[linear_index + 0] = pixel.x;
    output_data.elements[linear_index + 1] = pixel.y;
    output_data.elements[linear_index + 2] = pixel.z;
}
mTextureUniformHandle0 = GLES31.glGetUniformLocation(mProgramHandle,
                "u_Texture0");
// Set the active texture0 unit to texture unit 0.
        GLES31.glActiveTexture(GLES31.GL_TEXTURE0);

        // Bind the texture to this unit.
        GLES31.glBindTexture(GLES31.GL_TEXTURE_2D, mTextureDataHandle0);

        // Tell the texture uniform sampler to use this texture in the shader by
        // binding to texture unit 0.
        GLES31.glUniform1i(mTextureUniformHandle0, 0);
    public int[] initializeShaderBuffer(){
        android.opengl.EGLContext eglContext = eglGetCurrentContext();
        int[] id = new int[1];
        GLES31.glGenBuffers(id.length, id, 0);
        GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, id[0]);
        GLES31.glBufferData(GLES31.GL_SHADER_STORAGE_BUFFER, 257*257*3*4, null, GLES31.GL_STREAM_COPY);
        GLES31.glBindBufferBase(GLES31.GL_SHADER_STORAGE_BUFFER,1,id[0]);
        GLES31.glBindBuffer(GLES31.GL_SHADER_STORAGE_BUFFER, 0);// unbind
        return id;
    }

@ anilsyan7

Saya sedang tidak di kantor untuk berlibur minggu ini dengan akses jaringan terbatas dan ada kemungkinan besar saya akan melupakan hal ini. Bisakah Anda menyenggol saya lagi minggu depan?

Tentu porygon ... 😉

Hai @impjay ,
Bisakah Anda membantu kami dengan masalah ssbo tflite inferecne ?? Kami tidak dapat menjalankan inferensi tflite menggunakan ssbo di android. Bisakah Anda membagikan contoh aplikasi klasifikasi menggunakan ssbo atau setidaknya kode terkait opengl? Berapa kecepatan yang dapat kami harapkan dalam skenario ini?

Hai @impjay ,
Saya akan meminta permintaan untuk demo yang menggambarkan inferensi SSBO.

Mungkin saya harus membuka masalah terpisah ... Kami mencoba menggunakan GLSurfaceView di aplikasi kami, di samping tflite GPUDelegate. Penyaji kami berfungsi dengan baik sampai interpreter.modifyGraphWithDelegate(delegate); dipanggil, yang menghasilkan layar hitam. Tidak ada glErrors yang dihasilkan. Sulit untuk memahami bagaimana mengomentari / menghapus komentar pada baris di atas mengubah perilaku, bahkan setelah melihat sumber delegasi GPU yang baru dirilis.

Contoh yang berhasil mungkin menjernihkan semuanya ...

Terima kasih!

@ anilsyan7

Heh, saya melewatkan bagian porygon sebelumnya :)

Di bawah ini ada dalam C ++, tetapi harus serupa di Java juga.

    glActiveTexture(GL_TEXTURE0 + 0);
    glBindTexture(GL_TEXTURE_2D, /*your gl texture that has the image*/);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, 1, /*your ssbo*/, 0, /*size in bytes*/);
    glUseProgram(/*the program above*/);
    glDispatchCompute(width / 16, height / 16, 1);  // these are work group sizes
    glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);  // unbind
    glBindTexture(GL_TEXTURE_2D, 0);  // unbind

@kkt

Hm, satu-satunya contoh kode resmi adalah aplikasi demo TFLite yang ada di repositori TF. Karena aplikasi Android terdiri dari lebih dari satu file Java, itu akan sulit kecuali saya memulai repo git baru dengan file tersebut. Sayangnya, di atas semua itu, saya bukanlah pengembang aplikasi seluler sungguhan; Saya melakukan sebagian besar pekerjaan saya di Android C ++ tanpa kamera. Saya akan melihat apakah saya bisa memasak biner C ++ yang dapat melakukan semua ini dalam satu file C ++ = / Disamping diskusi itu ...

modifyGraphWithDelegate sepertinya Anda memiliki masalah di tempat lain. Pastikan bahwa TfLiteGpuDelegateBindBufferToTensor dipanggil sebelum modifyGraphWithDelegate , dan SSBO Anda sudah dibuat. Alur program dengan modifyGraphWithDelegate adalah sebagai berikut:

Interpreter.modifyGraphWithDelegate (Jawa)
Interpreter::ModifyGraphWithDelegate (C ++)
tflite::gpu::gl::(anonymous)::DelegatePrepare (C ++)
tflite::gpu::gl::(anonymous)::Delegate::Prepare (C ++)

Anda mungkin bisa melacak kembali apa yang menyebabkan gantung itu.

@ anilsyan7

Apakah semuanya berhasil? Bisakah masalah ini ditutup?

Kode berfungsi dengan baik; tetapi kami tidak bisa mendapatkan keluaran yang benar dengan menggunakan ssbo sebagai masukan. Keluarannya tampak hitam (yaitu keluaran semuanya nol). Kami tidak dapat memastikan bahwa data disalin dengan benar ke ssbo atau apakah itu diakses dengan benar oleh tensorflow ; meskipun berjalan tanpa kesalahan. Sepertinya tidak ada cara untuk men-debug dan melihat kode shader (GLSL) di android.

Terlampir dengan ini adalah file log yang berisi kesalahan saat kami mencoba menggunakan SSBO dengan model tflite.
Kode berfungsi dengan baik di Seluler dengan Adreno-GPU tanpa kesalahan apa pun tetapi tidak ada output yang divisualisasikan. Namun di ponsel dengan Mali-GPU, ada beberapa masalah bahkan sebelum model tersebut muncul.

Kesalahan bervariasi antara Perangkat Mali, sedangkan output tidak dapat divisualisasikan di Perangkat Adreno.
Perangkat yang digunakan dalam pengujian di bawah ini adalah:

Mali (Log kesalahan dilampirkan dengan masalah: mali-gpu-ssbo-errorlog.txt)
_Samsung A8 + _
_Honor Play_
_Moto C plus_

Adreno (Log Kesalahan terpasang: adreno-gpu-ssbo-errorlog.txt)
_Poco F1_

mali-gpu-ssbo-errorlog.txt

adreno-gpu-ssbo-errorlog.txt

@impjdi Bisakah Anda melihatnya .. Dan akan lebih baik jika Anda dapat berbagi dengan kami kode aplikasi yang berfungsi untuk referensi.

@impjdi Adakah pembaruan di SSBO ??

Hai @impjay ,
Saya akan meminta permintaan untuk demo yang menggambarkan inferensi SSBO.

Mungkin saya harus membuka masalah terpisah ... Kami mencoba menggunakan GLSurfaceView di aplikasi kami, di samping tflite GPUDelegate. Penyaji kami berfungsi dengan baik sampai interpreter.modifyGraphWithDelegate(delegate); dipanggil, yang menghasilkan layar hitam. Tidak ada glErrors yang dihasilkan. Sulit untuk memahami bagaimana mengomentari / menghapus komentar pada baris di atas mengubah perilaku, bahkan setelah melihat sumber delegasi GPU yang baru dirilis.

Contoh yang berhasil mungkin menjernihkan semuanya ...

Terima kasih!

@ktgordon Sudahkah Anda menemukan resolusi / solusi untuk masalah ini? Saya mengalami masalah yang persis sama. Setelah memanggil modifikatorraphWithDelegate (), semua panggilan glDraw menghasilkan warna hitam. Bahkan tidak perlu menghubungkan buffer SSBO ke TFLite Tensor. Ini aneh. Melihat lebih dalam juga.

Kami menemukan solusi. Saya berasumsi Anda menggunakan Java API dan membawa masuk delegasi GPU melalui
implementation 'org.tensorflow:tensorflow-lite:0.0.1-gpu-experimental'

Apa yang saya pikir terjadi adalah bahwa modifikatorGraphWithDelegate () memodifikasi konteks saat ini sehingga permukaan tampilan kita tidak lagi terkini ... tidak menjadi masalah jika kita memiliki akses ke variabel keadaan asli kita. Namun, karena kami awalnya mencoba menggunakan GLSurfaceView, kami tidak memiliki akses ke salah satu variabel ini. Akibatnya, modifikasikanGraphWithDelegate membuat perubahan pada status gl yang tidak dapat kami pulihkan.

Beralih dari GLSurfaceView ke TextureView memberi kami lebih banyak kontrol dengan biaya lebih banyak kerumitan. Kita membuat konteks tiruan, menginisialisasi penafsir kita dan memanggil modifikasikanGraphWithDelegate (), lalu membuat konteks bersama baru dengan konteks tiruan. Dengan cara ini kita bisa membuat permukaan tampilan kita saat ini dan merendernya.

Mengelola konteks egl ditangani dengan menggunakan kembali kode dari Grafika .

Ini membuat kami melewati masalah layar hitam ...

Saya melakukan persis seperti yang Anda katakan di sini karena saya berdasarkan demo TFLite (yang menggunakan TextureView). Terutama sebagai berikut:

  1. Buat konteks gl, setel gl viewport, dll. Menyimpan eglDisplay, eglSurface, eglContext.
  2. Lakukan panggilan ke modifyGraphWithDelegate() .
  3. Setel eglContext, eglSurface, eglDisplay sebagai yang terkini menggunakan eglMakeCurrent

Pengundian menggunakan glDrawArrays , hasilnya hitam. Menariknya, jika langkah 1 & langkah 2 ditukar secara berurutan, semuanya berfungsi.

Kode Grafika juga direferensikan.

Akan mencoba menyiapkan konteks tiruan selanjutnya ...

Hai @ktgordon , @gnrky ,
Apakah Anda menyarankan bahwa metode ssbo tidak akan berfungsi dengan GLSurfaceView normal? Bagaimana dengan GLTextureView ( link1 , link2 )?

Terakhir, apakah Anda dapat mencapai kecepatan apa pun dibandingkan dengan inferensi GPU normal? Jika demikian, dapatkah Anda membagikan aplikasi demo kerja dasar? Hanya untuk menjernihkan semuanya ...

@ktgordon Baru saja berhasil! Memang, konteks bersama dummy adalah kunci untuk membuatnya berhasil. Saya kira pengaturan / pengalihan konteks GLES bisa jauh lebih rumit daripada yang bisa dibayangkan ...

@ anilsathyan7 Saya berdasarkan demo TFLite , yang merupakan proyek contoh utama yang disediakan halaman delegasi GPU TFLite . Proyek contoh ini menggunakan TextureView . Tidak tahu apakah SSBO berfungsi dengan jenis permukaan lainnya. Saya membayangkan seharusnya eglCreateWindowSurface() membutuhkan SurfaceView , SurfaceTexture , SurfaceHolder atau Surface , menurut dokumen Android eglSurface . GLTextureView dari tautan Anda memperluas SurfaceTexture, seharusnya juga berfungsi.

Peningkatan kinerja itu signifikan . Saya mencoba gambar 448x448. (Mencoba gambar yang lebih besar untuk memperkuat waktu salin). Waktu yang dibutuhkan tanpa copy shader SSBO / Image2D adalah sekitar 900ms pada Snapdragon 808. Menggunakan copy shader waktunya turun ke <20ms!

@gnsmrky Bisakah Anda membagikan repo Anda, sehingga bisa menjadi hal yang lebih baik bagi semua orang untuk mulai menjelajahi ssbo dengan itu.

@gnsmrky Bisakah Anda membagikan repo Anda, sehingga bisa menjadi hal yang lebih baik bagi semua orang untuk mulai menjelajahi ssbo dengan itu.

@SanthoshRajendiran Mencoba mencari waktu untuk melakukan itu. Kode sekarang sangat berantakan dan tidak dapat dibaca. Akan membersihkannya segera setelah saya mendapatkan sepeda cadangan.

@gnsmrky @impjdi Ada kabar terbaru tentang repo ?? Dapatkah Anda memberikan beberapa fragmen kode tempat perubahan perlu dimasukkan ke dalam aplikasi seluler ??

@gnsmrky terima kasih banyak atas usaha anda. beri tahu kami saat Anda menambahkan kode contoh di sini.

@SanthoshRajendiran @ soham24 Rencanakan untuk menerbitkan repo selama akhir pekan. Masih melakukan beberapa penyesuaian. :)

@Santrikece

Saya meluapkan permintaan ini dalam beberapa pertemuan terakhir. Contoh akan ditambahkan ke aplikasi demo TFLite, tetapi saya memiliki beberapa tenggat waktu yang akan datang, jadi perlu beberapa bulan sampai saya bisa mendapatkannya :(

@SanthoshRajendiran @ soham24 @impjdi
Saya baru saja memasang repo di demo pengklasifikasi Android tensorflow-lite-ssbo . Sebaiknya buka saja proyek di Android Studio untuk membangun dan menjalankan. Setelah berada di aplikasi di ponsel, pilih GPU dan mobilenet v1 float untuk melihat copy time untuk waktu yang diperlukan untuk menyalin bingkai ke SSBO.

Kodenya masih sangat kasar. Tetapi harus melayani tujuan untuk mulai bermain-main dengan SSBO di delegasi GPU TFLite.

Di LG G4 saya (Android M, Snapdragon 808), waktu yang diperlukan untuk menyalin buffer 224x224 piksel berkurang secara signifikan. Dari 180ms ~ 200ms (Java ByteBuffer putFloat() copy), turun ke 1ms (shader + SSBO). Karena LG G4 adalah ponsel yang relatif lama (> 5 tahun sekarang), waktu yang dihemat pada ponsel yang lebih baru mungkin tidak terlalu signifikan. Tapi sungguh, jika G4 bisa melakukan copy frame dalam <1ms, pasti ponsel Android lain bisa melakukannya dengan lebih baik. :)

Pada dasarnya yang dilakukannya adalah sebagai berikut:

  1. Inisialisasi GLES Konteks A ( eglContext ).
  2. Buat tekstur permukaan untuk kamera.
  3. Buat SSBO
  4. Buat shader komputasi yang diperlukan untuk menyalin tekstur permukaan ke SSBO.
  5. Inisialisasi GLES Konteks B ( gpuContext ) dengan Konteks A sedang dibagikan.
  6. Panggil modifikasikanGraphWithDelegate ()
  7. Lakukan pengalihan konteks yang tepat menggunakan eglMakeCurrent ()

    • Beralih ke Konteks A saat kamera -> tekstur permukaan -> SSBO.

    • Beralih ke Konteks B saat memanggil TFLite Interpreter.run() .

Catatan: Saya tidak membuat utas terpisah untuk menyederhanakan proses. Biasanya Konteks A & B harus berada dalam 2 utas terpisah, jadi eglMakeCurrent () hanya dipanggil sekali dalam utas.

Belum punya waktu untuk membaca readme. Lihat saja komitnya . Harus cukup mudah untuk mencari tahu apa yang ada di sana. Semoga ini bisa membantu menjelaskan beberapa hal tentang TFLite + GPU delegate + SSBO.

Beri tahu saya jika ini berhasil untuk kalian ...

@gnsmrky Selamat dan terima kasih atas kerja luar biasa di SSBO. Kami mencoba aplikasi tersebut di beberapa ponsel kami. Metodologi kerja pada berbagai ponsel dibahas di bawah ini:

1) Oneplus 3 - Model waktu berjalan sekitar 40ms, sama seperti tanpa SSBO. Waktu salin sekitar 0 atau 1 dalam semua kasus
2) Poco F1 - Model waktu berjalan sekitar 25ms, Tapi kami tidak bisa mendapatkan hasil sebenarnya dari aplikasi.
3) Samsung A8 +, Honor Play - Aplikasi macet dengan kesalahan tautan, mengatakan jumlah maksimum permintaan grup kerja. Kami memodifikasi ukuran untuk kelompok kerja menjadi 8, dan kami memperoleh waktu berjalan model 5ms, tetapi kami tidak bisa mendapatkan keluaran yang sesuai dari model.

@ ggnrr, terima kasih banyak. Saya akan memberi tahu Anda tentang bekerja setelah implementasi.

@gnrrh Bagus kerja. Terima kasih banyak! Apakah Anda mencoba model segmentasi tab dalam?

@gnsmrky Selamat dan terima kasih atas kerja luar biasa di SSBO. Kami mencoba aplikasi tersebut di beberapa ponsel kami. Metodologi kerja pada berbagai ponsel dibahas di bawah ini:

  1. Oneplus 3 - Model waktu berjalan sekitar 40ms, sama seperti tanpa SSBO. Waktu salin sekitar 0 atau 1 dalam semua kasus

Jadi hanya berfungsi dan memiliki output yang tepat di OnePlus 3 di antara ponsel ini? Biarkan saya melihat apakah saya bisa mendapatkan ponsel Snapdragon 845.

@gnrrh Bagus kerja. Terima kasih banyak! Apakah Anda mencoba model segmentasi tab dalam?

@junhwanjang Saya belum mencoba deeplab. Tapi saya mencoba keluaran SSBO dengan model lain, yang bekerja dengan baik juga. Apakah deeplab berfungsi dengan GPU Delegate sepenuhnya, tahukah Anda?

@SanthoshRajendiran Saya baru saja memperbarui repo. Sepertinya shader komputasi membutuhkan permukaan tampilan yang nyata di beberapa perangkat. Saya menambahkan tampilan 1dp x 1dp ke aset untuk mengaitkannya dengan permukaan gles. Dapatkah Anda mencoba lagi repo yang diperbarui di ponsel Anda?

Ini komit terbaru.

BTW, Cam -> salinan SSBO tidak memperhitungkan transformasi dari updateTexImage() . Anda mungkin perlu memposisikan penghitung telepon Anda sesuai arah jarum jam (yaitu bagian bawah telepon mengarah ke kanan) untuk mendapatkan hasil inferensi yang benar.

@gnrky Terima kasih atas pembaruannya. Dengan POCO F1 (Adreno 630, Snapdragon 845), outputnya sekarang sekitar kecepatan 20-30ms dan waktu salin sekitar 0-1ms.
Masih masalah tetap ada di Perangkat GPU Mali (diuji di Honor Play)
Terlampir di bawah ini adalah log kesalahan dengan Honor Play:

mali-ssbo-android-errorlog.txt

@SanthoshRajendiran Sudahkah Anda mencoba mengatur grup kerja ke 8, atau bahkan 4, untuk perangkat Mali? Berikut adalah 2 baris yang harus Anda ubah 16 menjadi 8 atau 4 .
local_size di compute shader @ L1092
glDispatchCompute @ L1162

@gnsmrky Kami mencoba mengatur grup kerja sebagai 4 dan 8 di Samsung A8 +, model tidak berjalan dengan baik bahkan ketika kami mencobanya dalam mode lanskap. Saat kami mengubah grup kerja, aplikasi mogok dalam beberapa waktu karena kesalahan memori GL.

E / AndroidRuntime: FATAL EXCEPTION: CameraBackground
Proses: android.example.com.tflitecamerademo, PID: 23378
java.lang.IllegalArgumentException: Kesalahan internal: Gagal dijalankan pada Interpreter yang diberikan: Operasi selanjutnya tidak didukung oleh delegasi GPU:
SQUEEZE: Operasi tidak didukung.
29 operasi pertama akan dijalankan pada GPU, dan 2 sisanya pada CPU.TfLiteGpuDelegate Invoke: [GL_OUT_OF_MEMORY]: Memori tidak cukup untuk menjalankan perintah. Nomor kode 31 (TfLiteGpuDelegate) gagal dipanggil.

    at org.tensorflow.lite.NativeInterpreterWrapper.run(Native Method)
    at org.tensorflow.lite.NativeInterpreterWrapper.run(NativeInterpreterWrapper.java:149)
    at org.tensorflow.lite.Interpreter.runForMultipleInputsOutputs(Interpreter.java:275)
    at org.tensorflow.lite.Interpreter.run(Interpreter.java:249)
    at com.example.android.tflitecamerademo.ImageClassifierFloatMobileNet.runInference(ImageClassifierFloatMobileNet.java:101)
    at com.example.android.tflitecamerademo.ImageClassifier.classifyFrameSSBO(ImageClassifier.java:167)
    at com.example.android.tflitecamerademo.Camera2BasicFragment.classifyFrameSSBO(Camera2BasicFragment.java:967)
    at com.example.android.tflitecamerademo.Camera2BasicFragment.access$1200(Camera2BasicFragment.java:91)
    at com.example.android.tflitecamerademo.Camera2BasicFragment$8.run(Camera2BasicFragment.java:785)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:214)
    at android.os.HandlerThread.run(HandlerThread.java:65)

I / Proses: Mengirim sinyal. PID: 23378 SIG: 9

@gnsmrky Secara default di model seperti deeplab (model tidak sepenuhnya mampu berjalan di GPU), terjadi fallback di GPU Delegate dari GPU ke CPU. Apakah perilaku ini berubah di SSBO dan bagaimana cara kami mendapatkan data jika kembali ke CPU?

@ ggn terima kasih. ini berfungsi seperti pesona pada perangkat kelas bawah.
Satu pertanyaan, Memang benar kita harus memutar telepon berlawanan arah jarum jam. Dapatkah saya menambahkan logika berputar di shader.
tautan ref: https://stackoverflow.com/questions/28074977/rotating-a-texture-on-a-fragment-shader-in-glsl-es

@gnsmrky Bisakah Anda memberikan wawasan tentang perubahan apa yang harus dilakukan dalam kode aplikasi Anda jika saya ingin mendapatkan keluaran gambar dari model tflite, sehubungan dengan SSBO.

@gnsmrky Kami mencoba mengatur grup kerja sebagai 4 dan 8 di Samsung A8 +, model tidak berjalan dengan baik bahkan ketika kami mencobanya dalam mode lanskap. Saat kami mengubah grup kerja, aplikasi mogok dalam beberapa waktu karena kesalahan memori GL.

@SanthoshRajendiran Saya baru saja memperbarui repo dengan beberapa penyesuaian. Harus menurunkan kebutuhan memori yang besar.

  1. Gunakan presisi FP16.
  2. Gunakan 8 sebagai ukuran grup kerja.
  3. Tambahkan cek untuk ukuran buffer SSBO setelah pembuatan.

Kesalahan SQUEEZE Anda lihat mungkin disebabkan oleh kegagalan saat membuat buffer SSBO. Apakah Anda menjalankan repo apa adanya?

Beri tahu saya jika repo yang diperbarui berhasil untuk Anda.

@gnsmrky Secara default di model seperti deeplab (model tidak sepenuhnya mampu berjalan di GPU), terjadi fallback di GPU Delegate dari GPU ke CPU. Apakah perilaku ini berubah di SSBO dan bagaimana cara kami mendapatkan data jika kembali ke CPU?

@SanthoshRajendiran SSBO di repo hanya untuk buffer input. Tidak ada yang diubah untuk buffer keluaran. Jadi kode untuk mendapatkan data keluaran harus sama seperti yang Anda lakukan dengan CPU (yaitu ByteBuffer).

Saya belum mendapatkan deeplab. Apakah Anda tahu op mana yang menyebabkan mundurnya CPU?

@ ggn terima kasih. ini berfungsi seperti pesona pada perangkat kelas bawah.
Satu pertanyaan, Memang benar kita harus memutar telepon berlawanan arah jarum jam. Dapatkah saya menambahkan logika berputar di shader.
tautan ref: https://stackoverflow.com/questions/28074977/rotating-a-texture-on-a-fragment-shader-in-glsl-es

@ soham24 Transformasi terjadi saat Anda menggunakan glViewPort biasa, glDraw, dll. dengan shader vertexfragment yang sesuai. Kode SSBO di repo adalah salinan float memori sederhana dan tidak melibatkan shader vertex / fragmen apa pun. Jika kita melakukan transformasi pada basis per-float, kemungkinan besar akan memperlambat segalanya.

Cara terbaik untuk melakukannya adalah dengan "menggambar" tekstur kamera ke tekstur lain, dengan transformasi yang diinginkan, lalu melakukan tekstur -> salinan SSBO. Itu membutuhkan usaha. Akan perlu mencari lebih banyak waktu untuk melakukan itu.

@gnsmrky Bisakah Anda memberikan wawasan tentang perubahan apa yang harus dilakukan dalam kode aplikasi Anda jika saya ingin mendapatkan keluaran gambar dari model tflite, sehubungan dengan SSBO.

@SanthoshRajendiran Apa yang ingin Anda lakukan dengan keluaran gambar? Membuat SSBO dan mengikatnya ke delegasi GPU TFLite semudah membuat satu dan memanggil bindGlBufferToTensor() ke tensor keluaran getOutputTensor() , seperti yang disebutkan dalam dokumen Delegasi GPU .

@ ggn terima kasih. ini berfungsi seperti pesona pada perangkat kelas bawah.
Satu pertanyaan, Memang benar kita harus memutar telepon berlawanan arah jarum jam. Dapatkah saya menambahkan logika berputar di shader.
tautan ref: https://stackoverflow.com/questions/28074977/rotating-a-texture-on-a-fragment-shader-in-glsl-es

@ soham24 Transformasi terjadi saat Anda menggunakan glViewPort biasa, glDraw, dll. dengan shader vertexfragment yang sesuai. Kode SSBO di repo adalah salinan float memori sederhana dan tidak melibatkan shader vertex / fragmen apa pun. Jika kita melakukan transformasi pada basis per-float, kemungkinan besar akan memperlambat segalanya.

Cara terbaik untuk melakukannya adalah dengan "menggambar" tekstur kamera ke tekstur lain, dengan transformasi yang diinginkan, lalu melakukan tekstur -> salinan SSBO. Itu membutuhkan usaha. Akan perlu mencari lebih banyak waktu untuk melakukan itu.

Terima kasih @gnrky . Akan lebih bagus jika Anda memperbarui sampel dengan transformasi yang diinginkan.

@gnsmrky Kami menemukan masalah dengan operasi Squeeze tidak didukung. Itu karena, secara default operasi Squeeze tidak berfungsi di GPU pada Perangkat Mali (diverifikasi dengan alat benchmark). Harapan, kami akan membuka masalah terpisah untuk itu, atau karena @impjdi ditautkan dengan utas, dia akan menanganinya .. Selain itu, repo berfungsi sebagaimana adanya ... Dalam kasus kami, kami menangani GPU penuh model yang didukung dan mendapatkan keluaran gambar untuk ditampilkan ke permukaan, jadi, kami akan melanjutkan dengan keluaran SSBO juga ..

@SanthoshRajendiran Saya ragu. Apakah Anda mengubah ukuran tekstur ukuran input sebelum meneruskannya ke tflite?
op akan diubah ukurannya. Bagaimana Anda akan merendernya secara langsung melalui tekstur?

@ soham24 Masukan ke model yang akan kita ubah ukurannya untuk memastikan model berjalan .. Keluaran model akan kita ubah ukurannya ke ukuran yang diinginkan yang perlu kita render.

@ soham24 Masukan ke model yang akan kita ubah ukurannya untuk memastikan model berjalan .. Keluaran model akan kita ubah ukurannya ke ukuran yang diinginkan yang perlu kita render.

@SanthoshRajendiran Kedengarannya aneh juga bagi saya. Apa yang saya coba katakan adalah bahwa jika ukurannya tidak sesuai untuk SSBO, delegasi GPU akan mengatakan SQUEEZE bermasalah, padahal bukan itu masalahnya.

Terima kasih @gnrky . Akan lebih bagus jika Anda memperbarui sampel dengan transformasi yang diinginkan.

Pekerjaan sedang dalam proses, meskipun sangat lambat ...

Dalam versi aplikasi saat ini, itu dikembangkan dengan EGL Surface. Kami mencoba menggunakan GL Surface View, tetapi tidak berhasil. Apakah ada solusi yang dapat dilakukan untuk memfasilitasi output ssbo untuk dirender secara langsung pada GL Surface View?

@gnsmrky Kami mencoba mencari tahu Output SSBO, tetapi kami tidak dapat melakukannya dengan benar .. Dapatkah Anda memberi tahu kami tempat persisnya yang kami perlukan untuk melakukan perubahan agar dapat berfungsi.

Pada dasarnya, kami melakukan modifikasi ini.
1) Inisialisasi instance tflite dengan menyetel setAllowBufferHandleOutput (true) sesuai dokumentasi gpu tflite.
2) Output buffer terikat ke model SSBO menggunakan gpuDelegate.bindGlBufferToTensor (outputTensor, outputSsboId);

3) Memberikan output di layar ponsel.

Bisakah Anda memeriksa apakah keluaran SSBO berfungsi dalam kasus Anda .. Atau beberapa perubahan yang telah dilakukan sebelumnya seperti memutar layar atau sesuatu yang diperlukan sekarang juga untuk memvisualisasikan keluaran di layar ..

Dengan ini, saya telah melampirkan tflite yang kami gunakan untuk menguji keluaran SSBO, di mana kami tidak melakukan apa-apa, tetapi hanya mengubah ukuran gambar dari 197 menjadi 257 menggunakan operasi ResizeBilinear.

just_resize_ssbo.tflite.zip

Bisakah Anda memeriksa apakah keluaran SSBO berfungsi dalam kasus Anda .. Atau beberapa perubahan yang telah dilakukan sebelumnya seperti memutar layar atau sesuatu yang diperlukan sekarang juga untuk memvisualisasikan keluaran di layar ..

@SanthoshRajendiran Saya tidak melakukan apa pun untuk keluaran SSBO di repo yang saya posting di sini. Tapi saya keluaran SSBO berfungsi. Jadi mungkin ada sesuatu dalam kode shader Anda yang memindahkan data dari SSBO ke buffer tekstur untuk menggambar di layar.

Apa yang saya sarankan adalah mencoba operasi yang tidak mengubah bentuk apapun. sqrt op sebagai salah satu contoh, yaitu op unary yang tidak merubah bentuk tensor. Isi nilai yang bisa diprediksi, katakan 100 , hasilnya harus 10 . Begitulah cara saya mengerjakan kedua input / output SSBO di awal.

Sebagian besar masalah yang saya hadapi bukanlah pada bagian delegasi TFLite GPU, tetapi pada OpenGL ES di Android. Hanya perlu membedah kode sepotong demi sepotong agar berfungsi dengan benar dari SSBO ke layar.

Semoga ini membantu...

BTW, cobalah untuk tidak menggunakan Bilinear Resize dengan pengubahan ukuran non-integral terlebih dahulu. Cobalah sesuatu seperti 2 sebagai faktor penskalaan. Jadi 157 akan diubah ukurannya menjadi 314 . Ini mungkin membantu ...

Halo, @gnsmrky :
Saya menguji kode Anda di dua perangkat berbeda dan tampaknya hanya menggunakan GPU secara acak. Sebagian besar waktu saat dalam mode GPU tidak melakukan apa-apa. Saya mencoba lebih sedikit kelompok kerja (8 atau 4) tetapi tidak ada bedanya ...

Apakah Anda tahu mengapa ini terjadi?

Terima kasih sebelumnya.

Saya menguji kode Anda di dua perangkat berbeda dan tampaknya hanya menggunakan GPU secara acak. Sebagian besar waktu saat dalam mode GPU tidak melakukan apa-apa. Saya mencoba lebih sedikit kelompok kerja (8 atau 4) tetapi tidak ada bedanya ...

@jsolves Bisakah Anda menjelaskan lebih lanjut? Apakah maksud Anda Kamera -> SSBO tidak berfungsi, atau delegasi GPU? Bagaimana Anda mengamati apakah itu berhasil atau tidak?

Saya harap saya bisa memberi tahu Anda lebih banyak. Tetapi setiap mode di aplikasi berfungsi dengan benar hingga beralih ke GPU. Sebagian besar waktu, mengklasifikasikan semuanya sebagai 0% atau mendekati 0% dan pemanfaatan gpu perangkat tidak naik. Hanya dalam beberapa kesempatan, klasifikasi GPU berjalan dengan baik (dan penggunaan GPU meningkat, karenanya).

Saya mencoba "aplikasi gpu" lain dan berfungsi sebagaimana mestinya. Saya tidak tahu bagaimana menentukan apakah masalahnya adalah Kamera -> SSBO atau delegasi GPU atau sesuatu yang terkait dengan shader. Apakah Anda tahu sesuatu yang bisa saya coba untuk melihat apakah masalahnya adalah salah satunya?

Terima kasih atas jawaban anda.

Saya mencoba "aplikasi gpu" lain dan berfungsi sebagaimana mestinya. Saya tidak tahu bagaimana menentukan apakah masalahnya adalah Kamera -> SSBO atau delegasi GPU atau sesuatu yang terkait dengan shader. Apakah Anda tahu sesuatu yang bisa saya coba untuk melihat apakah masalahnya adalah salah satunya?

@jsolves Yang pasti bisa Anda coba adalah repo Android Tensorflow Lite asli, yang sudah didukung GPU. Repo SSBO saya hanya menambahkan kamera -> SSBO berdasarkan repo ini. Anda dapat melihat apakah GPU di repo Android TFLite memiliki waktu inferensi yang lebih cepat.

Ah, maaf, saya sedikit lelah dengan masalah ini. Ya, Delegasi GPU berfungsi dengan benar di repo asli dan di aplikasi kustom saya sendiri. Ini memberikan waktu inferensi lebih cepat daripada inferensi CPU.

Jadi masalahnya ada di kamera-> bagian SSBO, lalu?

Jadi masalahnya ada di kamera-> bagian SSBO, lalu?

@jsolves Tujuan utama SSBO adalah untuk mengurangi waktu penyalinan piksel dari Kamera untuk memasukkan SSBO untuk TFLite. Waktu inferensi GPU seharusnya tidak terpengaruh sama sekali.

Apakah Anda melihat "waktu salin" saat menjalankan aplikasi saat menjalankan mode GPU?

Juga, bagaimana Anda memeriksa pemanfaatan GPU? Apakah Anda mendapatkan keluaran inferensi yang diharapkan saat pemanfaatan GPU rendah?

Ya saya tahu. Dalam GPU (dengan SSBO) waktu penyalinan sangat rendah (0 - 2) tetapi tidak ada klasifikasi yang tepat (nilai acak atau semua 0) hampir sepanjang waktu.

Dalam konfigurasi perangkat, ada opsi seperti "tampilkan pemanfaatan gpu" dan dalam beberapa kali aplikasi berfungsi dengan baik (dengan GPU), indikator gpu tersebut akan naik.

Ini seperti jika kamera gambar tidak selalu masuk ke SSBO atau masalah inisialisasi. Tapi Android-Fu saya tidak cukup kuat untuk mendapatkannya ... :(

@jsolves Saat saya menguji inferensi gpu dengan model input 3-saluran dasar, saya tidak bisa mendapatkan hasil yang benar.
Namun, ketika saya mengubah model dengan 3-channel menjadi input 4-channel palsu (menggunakan Input baru dan ops strided_slice), akhirnya mendapatkan hasil yang benar :)

https://www.tensorflow.org/lite/performance/gpu_advanced#tips_and_tricks

Menarik. Bagaimana Anda membuat "4-saluran palsu" itu, menyetel alfa "palsu" ke 1 di setiap piksel?

Terima kasih sebelumnya.

input_shape = (224, 224, 4)
inputs = Input(input_shape, dtype=np.float32)
x = Lambda(lambda x: x[:, :, :, :3])(inputs)
model_pre = Model(inputs, x)
model_pre.summary()
sess_fake = K.get_session()
graph_def_fake = sess_fake.graph_def
nodes_fake = [n for n in graph_def_fake.node]

Saya mengubah model sebagai berikut.

  1. Buat input palsu (termasuk operasi slice bertahap)
  2. Ubah input 3 saluran sebelumnya menjadi input palsu seperti di atas pada grafik (harus mengetahui nama input sebelumnya jika memungkinkan)
  3. Ubah model TFLite

Saya pikir https://mediapipe.dev melakukan ini.

@ soham24 Saya pergi melalui mediapipe, tetapi tidak dapat memahami cara kerjanya. Tflite yang disediakan oleh tim mediapipe, memiliki operasi yang tidak didukung oleh TFLite-GPU, atau bahkan operasi tensorflow seperti itu. Adakah yang bisa memberikan saran tentang cara melatih model segmentasi berdasarkan arsitektur mediapipe.

@SanthoshRajendiran Bahkan saya mencoba mencari tahu pipeline dengan melihat kode mediapipe.
Akan lebih bagus jika orang-orang di tf membantu kami

@SanthoshRajendiran @ soham24

Ya, MediaPipe mungkin menggunakan semua fitur delegasi GPU dan merupakan tempat yang baik untuk memulai (Saya pernah mengerjakan MediaPipe beberapa tahun yang lalu: D). Saya setuju bahwa jalur GPU tidak super mudah dibaca, tetapi masih merupakan tempat yang layak untuk memulai. Jika Anda melihat TfLiteInferenceCalculator , pertama-tama, Anda akan melihat banyak hal RunInGlContext , yang memastikan Anda tetap berada dalam konteks GL yang sama. Kemudian, yang benar-benar dilakukannya adalah, salin masukan SSBO, jalankan inferensi, dan salin keluaran SSBO. Saya pikir masih ada ruang untuk perbaikan, yang akan segera terjadi (tm). Nah, itulah yang ada di piringku selama 3 bulan ke depan: P

Untuk model segmentasi, Anda ingin memeriksa di halaman github MediaPipe dan melakukan ping ke orang-orang itu.

Bisakah kita memperbarui ini?

Ummm, bisakah Anda menjelaskan jenis pembaruan yang Anda harapkan? Apakah Anda ingin kami menelusuri perangkat lunak sumber terbuka lainnya?

Saya telah mencoba mengaitkan model tflite khusus saya ke SSBO di android seperti yang dilakukan @gnsmrky , tetapi
(Ngomong-ngomong, tflite terbaru tampaknya tidak mendukung bindGlBufferToTensor tetapi dokumen resmi tflite gpu delegate masih memperkenalkan bindGlBufferToTensor dalam menggunakan SSBO.)
Pokoknya saya telah membangun tensorflow dari https://github.com/gnsmrky/tensorflow-lite-ssbo dan berhasil menjalankan demo klasifikasi gambar dengan SSBO. Meskipun menunjukkan hasil yang berbeda dibandingkan dengan versi CPU dan versi GPU resmi tanpa SSBO, ini setidaknya berfungsi - memiliki nilai prediksi dan waktu penyalinan berkurang.
Tetapi ketika saya mengubah model mobilenet yang disediakan ke model kustom saya (saya telah mencoba bahkan model yang sangat sederhana dengan operasi tambahan saja), sepertinya berfungsi tetapi outputnya nol, atau terkadang menghasilkan kesalahan yang tidak terikat Tensor pegangan penyangga tergantung pada model yang digunakan.
Karena saya telah mencoba model dengan input 224x224x3 yang sama dengan demo asli dan tidak mengubah apa pun kecuali jalur model, saya ingin tahu apakah ada modifikasi lain yang harus saya tangani ketika saya mengubah atau membuat model.
Di bawah ini adalah beberapa contoh model sederhana yang pernah saya coba. (Divisualisasikan oleh Netron)
image
image
Akan sangat bagus jika TensorFlow menawarkan demo SSBO resmi dengan tflite terbaru.

tensorflow-lite-ssbo / tensorflow / lite / java / demo / app / src / main / java / com / example / android / tflitecamerademo / ImageClassifier. java: 212 : error: tidak dapat menemukan simbol
gpuDelegate.bindGlBufferToTensor (inputTensor, inputSsboId);
^
simbol: metode bindGlBufferToTensor (Tensor, int)
lokasi: variabel gpuDelegate jenis GpuDelegate
@jmhodges @gnsmrky

Saya tidak bekerja di tanah Java, dan karena itu saya tidak tahu delegasi Java API mana yang digunakan, tetapi bindGlBufferToTensor diganti namanya di delegasi GL yang tidak digunakan lagi, dan dihapus di delegasi GPU baru. Lihat //tf/lite/delegates/gpu/gl_delegate & //tf/lite/delegates/gpu/gpu_delegate .

@impjdi @jmhodges @gnsmrky
Nilai piksel input model saya mengambang dengan kisaran 0,0 - 1,0 (1,0 / 255) dapat menggunakan ssbo?

Bagaimana cara membuang buf ssbo ke cpu untuk mengevaluasi?

Anda sedang mencari glMapBufferRange

image
Mengapa transformedData mencetak nilai nol setelah glDispatchCompute dipanggil
Dimana salah
Saya perlu memperhatikan nilai ssbo setelah copyCamtextToSsbo jika memiliki metode yang lebih baik?
@impjdi @svenstaro @bmabey

Tidak terlalu paham dengan Java ByteBuffer dan FloatBuffer , tetapi apakah Anda tidak melewatkan glFinish sebelum Anda mulai membaca dari lokasi memori?

@impjdi @svenstaro @ktgordon @SanthoshRajendiran @gnsmrky
Anda bisa menganggap FloatBuffer sebagai float * pointer (buffer) di c ++
Saya telah mencoba dengan glFinish tetapi hasilnya sama
tetapi jika saya menambahkan kode ikuti:
GLES31.glBufferData (GL_SHADER_STORAGE_BUFFER, ssboSize, ssboData, GL_STREAM_COPY);
Saya bisa mendapatkan konten ssboData dengan glMapBufferRange mengapa?
image
image
image
Saya ingin mengevaluasi konten out_data.elements sudah benar? setelah pengiriman selesai.
Saya telah mencari di Google selama dua hari tetapi tidak menemukan solusi untuk itu

GLES31.glBufferData (GL_SHADER_STORAGE_BUFFER, ssboSize, ssboData, GL_STREAM_COPY);
Saya bisa mendapatkan konten ssboData dengan glMapBufferRange mengapa?

Tidak berbicara tentang bagian "mengapa", tetapi bukankah masalah Anda terpecahkan jika Anda dapat mengakses ssboData ?

Saya juga ingat bahwa saya tidak dapat menemukan cukup banyak contoh di web untuk membuat kemajuan yang wajar. Apa yang Anda tanyakan sekarang tampaknya sedikit di luar cakupan untuk dukungan GPU TFLite, karena Anda menanyakan pertanyaan shader komputasi OpenGLES murni. Saya sarankan untuk bertanya di forum Khronos dan / atau ikuti jalur kode di dalam TFLIte GPU dan MediaPipe; kedua framework ini banyak menggunakan SSBO dan tekstur. Saya yakin Anda akan menemukan kasus penggunaan Anda di sana.

@impjdi @svenstaro @ktgordon @SanthoshRajendiran @gnsmrky

Saya seorang pemula untuk opengl es.

Saya telah melihat MediaPipe dan Tflite GPU untuk mencoba menyelesaikannya tetapi gagal

Saya ingin tahu cara men-debug shader komputasi di android untuk Anda

itu memiliki beberapa hal di jaringan tentang ssbo

Kode disediakan oleh https://github.com/gnsmrky/tensorflow-lite-ssbo

Maaf untuk bahasa Inggris saya jika Anda tidak mengerti

Berhenti menyoroti saya.

@svenaro Sangat menyesal telah mengganggu Anda

@tokopedia
Saya akhirnya menemukan mengapa glmapbufferrange mengembalikan semua nol.
GL_OES_EGL_image_external_essl3 tidak berfungsi dengan beberapa perangkat android
https://community.arm.com/developer/tools-software/graphics/f/discussions/9432/is-extension-gl_oes_egl_image_external_essl3-not-working-properly-in-compute-shader-on-mali-g71-gpu

Ah, terima kasih atas pembaruan dan berbagi!

Saya mengikuti dokumentasi resmi untuk android untuk delegasi GPU dan juga terjebak di langkah bindBuffer.

Saya tidak bekerja di tanah Java, dan karena itu saya tidak tahu delegasi Java API mana yang digunakan, tetapi bindGlBufferToTensor diganti namanya di delegasi GL yang tidak digunakan lagi, dan dihapus di delegasi GPU baru. Lihat //tf/lite/delegates/gpu/gl_delegate & //tf/lite/delegates/gpu/gpu_delegate .

Saya memeriksa master saat ini dan tidak ada gpu_delegate (.cc?), Hanya gpu_delegate_jni (.cc). Apakah yang Anda maksud itu?

Bagaimanapun, saya menemukan bahwa TfLiteGpuDelegateBindBufferToTensor tampaknya merupakan simbol perpustakaan yang diekspor dan kita bisa mendapatkan pegangan asli dari delegasi sehingga kita mungkin bisa memanggil metode itu langsung dari java.

Maaf, file terakhir seharusnya //tf/lite/delegates/gpu/delegate.cc . Kami secara internal mencoba menggunakan bindBuffer (tanpa API delegasi, tetapi dengan fungsi internal GPU secara langsung) dan melihat bahwa API baru agak rusak, sehingga tidak dapat digunakan dengan API baru. Seseorang sedang berusaha memperbaikinya. Untuk saat ini, jika Anda ingin menggunakan bindBuffer , saya rasa Anda terjebak dengan API lama, yaitu gl_delegate .

@impjdi Terima kasih atas pembaruannya. Apakah itu berarti rute SSBO saat ini hanya tersedia dengan ikatan C atau tidak sama sekali?

Saya belum memeriksa Java, tetapi jika Java telah bermigrasi ke API baru (delegate.cc), penilaian Anda benar.

Untuk C ++, ini hanya tersedia di v1 (gl_delegate.cc), tetapi tidak di v2 (delegate.cc).

@impjdi adalah masalah bindBuffer SSBO di delegasi v2 diselesaikan?

Rencana saat ini bukan untuk mendukung bindBuffer di delegate v2.

@impjdi kami memiliki bingkai gambar kami di memori GPU. Haruskah kita memindahkannya ke CPU hanya untuk memulai inferensi, yang akan memindahkannya ke GPU lagi? Waktu yang dihabiskan untuk melakukan ini akan menyia-nyiakan manfaat inferensi gpu dalam banyak kasus.

@impjdi Bisakah Anda berbagi informasi tentang mengapa bindBuffer tidak akan didukung di delegate v2? Saya percaya bahwa ini meningkatkan waktu inferensi ujung ke ujung gpu dengan menghilangkan tindakan memcpy. Apakah tim tflite mengalami beberapa masalah yang tidak dapat diselesaikan atau keputusan dibuat hanya oleh persyaratan produk?

Ada banyak penggunaan lanjutan dari inferensi GPU seluler, dan untuk masing-masing, delegasi GPU memerlukan fungsi pembantu seperti bindBuffer karena tidak sesuai dengan kerangka kerja delegasi. Setelah menambahkan banyak dukungan untuk penggunaan yang diperpanjang baik melalui fungsi helper atau opsi, kami memutuskan itu tidak lagi dapat dipelihara dengan pertumbuhan kombinatorik dan memberikan tampilan yang tidak konsisten bahkan di dalam delegasi GPU (OpenCL, OpenGL, Metal, dll.). Perhatikan bahwa, kita harus membungkusnya dengan Java API. Dengan mayoritas pengguna yang menginginkan delegasi GPU hanya sebagai akselerator kotak hitam cepat, kami membuat keputusan akhir bahwa API delegasi akan tetap sederhana dan bersih. Untuk penggunaan tingkat lanjut yang mendukung pipeline eksekusi GPU yang efisien, kami masih memiliki kode contoh, misalnya TfLiteInferenceCalculator dari MediaPipe. Perhatikan bahwa ini belum ada, karena masih menggunakan delegasi v1 dan karenanya memiliki akses ke bindBuffer .

@impjdi Informasi ini berguna. Pertanyaan lainnya adalah kapan integrasi MediaPipe delegate v2 akan dirilis? Terima kasih.

Seseorang sedang mengerjakannya :)

Adakah yang berhasil mengikat buffer dengan delegasi v2?

Sepertinya saya sudah menggunakan mediapipe , lihat dalam kalkulator yang disebutkan oleh impjdi di bawah bendera use_advanced_gpu_api_ . Ini menggantikan aliran interpreter / delegasi dan menggunakan komponen tingkat rendah sebagai gantinya.

Ini sangat tidak bersahabat bagi mereka yang ingin memiliki utilitas SSBO tanpa memelihara penerjemah mereka sendiri, tetapi lebih dalam lagi, logika pengikatan ada di mediapipe / tflite_gpu_runner.cc dan cukup memanggil InferenceRunner::SetInputObject .

Delegasi v2 memiliki InferenceRunner itu sendiri jadi mungkin patch kecil untuk delegasi v2 dapat menambahkan panggilan SetInputObject (atau output) yang diperlukan. Tapi saya belum menguji, menyiapkan ini akan sulit bagi saya saat ini.

@impjdi ,

@ natario1 Saya rasa @impjdi menjelaskan bahwa bindBuffer API tidak cocok dengan desain delegasi v2. Perbedaan utama antara delegasi v1 & v2 adalah v2 mendukung OpenCL dan OpenGL backend sementara v1 hanya mendukung OpenGL. Ini akan memengaruhi cara Tflite menangani pertukaran kepemilikan data. Selain itu, banyak perangkat di pasar tidak sepenuhnya mendukung interoperabilitas OpenCL-OpenGL. Saya juga mencoba bendera use_advanced_gpu_api_ di MediaPipe, aplikasi macet saat saya menyalakannya. Jadi saya pikir ini bukan tambalan sepele bagi delegasi v2 untuk mendukung fitur bindBuffer . Jika Anda membutuhkan fitur ini, menurut saya solusi paling sederhana adalah tetap menggunakan mediapipe dengan backend opengl.

Terima kasih atas komentar Anda @ brucechou1983 . Solusi yang lebih sederhana bagi saya adalah tetap berpegang pada delegasi v1, tetapi jujur ​​saja sepertinya pelari mediapipe tidak melakukan sesuatu yang rumit / mewah, selain menelepon InferenceRunner::SetInputObject dan InferenceRunner::SetInputObjectDef saat mempersiapkan. Saya mengerti bahwa itu mungkin belum siap, karena di bawah bendera.

Delegasi v2 juga melakukan panggilan object / objectdef yang sama, tetapi perbedaannya adalah ia menggunakan ObjectType::CPU_MEMORY daripada ObjectType::OPENGL_SSBO seperti yang dilakukan mediapipe.

Saya tidak tahu apa yang mendukung OpenCL di Android, tetapi OpenGL berfungsi dengan baik, jadi kami dapat memiliki flag di opsi delegasi v2 yang memberi tahu delegasi untuk tidak mencoba OpenCL dan menggunakan OpenGL. Menurut saya, ini adalah sesuatu yang dapat ditambahkan oleh tim TF untuk memudahkan transisi v1-v2, karena orang yang menggunakan v1 kemungkinan besar telah menyiapkan SSBO.

@ natario1 Jika Anda membutuhkan sebuah flag untuk hanya menggunakan OpenGL, itu sudah ada meskipun masih eksperimental. Anda dapat menyetel benderanya menjadi TFLITE_GPU_EXPERIMENTAL_FLAGS_GL_ONLY .

Namun, ketika Anda membutuhkan segmentasi semantik realtime (>> 30fps) dan / atau face mesh yang berjalan pada ponsel seharga $ 200 dolar, memilih backend GPU yang tepat dalam runtime tflite untuk eksekusi yang efisien bukanlah masalah yang sepele. Saya melihat nilai menggunakan OpenCL untuk beberapa perangkat GPU MALI. Eksekusi invoke() 2x-3x lebih cepat dari OpenGL ES. Meskipun saya harus menyalin data ke / dari tensor, kinerja keseluruhan masih lebih baik. Saya pikir tim tflite sedang mencoba merancang delegasi v2 sebagai akselerator kotak hitam untuk tujuan umum / perangkat IoT sewenang-wenang / mudah digunakan, sambil membuat antarmuka untuk kerangka kerja lain seperti MediaPipe untuk mengoptimalkan penggunaan tertentu seperti eksekusi GPU yang efisien di seluler / desktop.

@ natario1 Saya melihat Anda melakukan pekerjaan rumah Anda di sana, kerja bagus 👍

Anda mungkin telah memperhatikan, tetapi TFLite menambahkan banyak delegasi untuk berbagai akselerator atau API. Masing-masing memiliki fungsi pembantu khusus tidak membantu penggunaan, tetapi membuatnya lebih membingungkan bagi 99% pengguna yang ingin menggunakan delegasi GPU TFLite hanya sebagai kotak ajaib yang melakukan inferensi yang dipercepat GPU. Jadi keputusan akhir yang kami buat adalah untuk membuat delegasi GPU TFLite sesederhana mungkin, tetapi biarkan ruangan terbuka untuk pengguna tingkat lanjut yang ingin melakukan hal-hal yang berkinerja nyata.

Tim yang mengirimkan GPU TFLite dan MediaPipe adalah tim saudara yang berbagi satu manajer. Karena itu, GPU TFLite tidak akan merusak MediaPIpe, dan itu jaminan. Dan dalam hal ini, masuk lebih dalam dan menggunakan API internal lanjutan seperti InferenceRunner::SetInputObject dengan cara yang aman digunakan MediaPipe. Tentu saja, karena ini bukan API publik, tetapi internal lanjutan, mungkin ada perubahan API yang mungkin mengganggu Anda sesekali, tetapi Anda akan selalu memiliki implementasi referensi MediaPipe.

Saya mengerti situasi @impjdi . Apakah Anda akan mempertimbangkan sesuatu seperti V2Delegate::GetInferenceRunner() ? Sehingga kita dapat memanggil InferenceRunner::SetInputObject atau apapun dari _outside_ delegasi.

Anda mengatakan bahwa SetInput/OutputObject dan SetInput/OutputObjectDef API adalah "lanjutan" dan mereka sampai batas tertentu, tetapi pada saat yang sama, masuk akal bahwa untuk mengikat tensor ke "sesuatu", satu harus menentukan tata letak datanya, ukuran, jenis objek, dan sebagainya. Mereka sebenarnya sangat elegan dan mudah dimengerti sehubungan dengan BindGlBufferToTensor , yang dari sudut pandang saya, hanya melakukan sihir yang tidak jelas di bawah tenda yang tidak dapat saya pahami.

API ini juga akan disembunyikan di balik GetInferenceRunner () API, yang dapat Anda dokumentasikan sebagai fungsi "gunakan dengan risiko Anda sendiri", dan menjaga permukaan kotak hitam tetap bersih. Saya pikir pendekatan ini benar-benar akan "membiarkan ruangan terbuka" seperti yang Anda katakan. (mungkin itu akan lebih berhasil bagi Anda daripada hanya menambahkan getter untuk pelari inferensi, tetapi Anda mengerti maksudnya - mampu mengontrol objek delegasi dari luar)

Selain itu, saya akan mencoba menggunakan API tingkat rendah ini akhir pekan ini dan melihat apakah saya berhasil menjalankan v2. Terima kasih telah membantu!

Sunting: Setelah menghabiskan akhir pekan untuk itu saya menyadari saran ini tidak mungkin, tetapi saya harap Anda dapat mempertimbangkan sesuatu seperti apa yang akhirnya saya lakukan yang bersih dan membuat tajuk delegasi tidak tersentuh.

@impjdi ada saran tentang cara memperbaiki kesalahan ini? Tampaknya ada masalah dengan konversi BHWC> BHWC4, tapi saya tidak tahu bagaimana mengatasinya. Itu terjadi di ToTensorConverter.

E/tflite:
    TfLiteGpuDelegate Invoke: Missing output in converter
    Node number 1 (TfLiteGpuDelegateV2) failed to invoke.

Saya membuat objek def dan objek tensor sebagai berikut:

// object def
tflite::gpu::ObjectDef object_def;
object_def.data_type = tflite::gpu::DataType::FLOAT32;
object_def.data_layout = tflite::gpu::DataLayout::BHWC;
object_def.object_type = tflite::gpu::ObjectType::OPENGL_SSBO;
object_def.user_provided = true;

// tensor object
tflite::gpu::OpenGlBuffer tensor_object;
tensor_object.id = ssbo;

Kemudian berikan keduanya kepada delegasi sebelum ModifyGraphWithDelegate . Mereka dengan benar diteruskan ke pelari inferensi dan pembangun pelari, namun saya mendapatkan kesalahan konverter itu.

Versi TF 2.2.0 dan model yang saya gunakan sangat sederhana, mengambil gambar 400x400x1 dan menghitung intensitas rata-rata, mengembalikan satu pelampung. Saya mencoba menggunakan objek SSBO untuk input saja.

Saya juga menjalankan backend OpenGL, OpenCL tidak tersedia di ponsel saya.

Setelah berjam-jam, saya rasa saya menemukan bug yang masih ada di 2.2.0, tetapi telah diperbaiki di master oleh komit ini: https://github.com/tensorflow/tensorflow/commit/4000a5c75cdbe49d77bcac93a7f21070a31c4cce https://github.com / tensorflow / tensorflow / komit / dffe6a0e810f4c3d9968ddb56fd58c8f405eb846

Bagi mereka yang tertarik, singkatnya, fakta bahwa saya menggunakan BHWC dengan 1 saluran warna (bukan 4), mengharuskan mesin gl untuk melakukan konversi dan konversi ini (sebelum https://github.com/tensorflow/ tensorflow / commit / 4000a5c75cdbe49d77bcac93a7f21070a31c4cce dan https://github.com/tensorflow/tensorflow/commit/dffe6a0e810f4c3d9968ddb56fd58c8f405eb846) benar-benar rusak, karena user_provided blob / v2.2.0 / tensorflow / lite / delegates / gpu / gl / api2.cc # L595) tetapi ketika user_provided benar, mesin tidak akan repot-repot membuat buffer GL keluaran (https: // github .com / tensorflow / tensorflow / blob / v2.2.0 / tensorflow / lite / delegates / gpu / gl / api2.cc # L199-L202), sehingga konversi C-> C4 tidak dapat terjadi.

Dengan memilih ceri https://github.com/tensorflow/tensorflow/commit/4000a5c75cdbe49d77bcac93a7f21070a31c4cce dan https://github.com/tensorflow/tensorflow/commit/dffe6a0e810f4c3d9968ddb56fd58c8f405eb846 , saya dapat membuka API yang diperlukan lakukan SSBO I / O dengan delegasi v2. Komitmen ini sudah cukup lama jadi saya berharap mereka dapat melakukannya ke rilis berikutnya.

Ini adalah perubahan yang harus saya lakukan untuk mengekspos API yang diperlukan: https://github.com/natario1/tensorflow/commit/7401fbb4fa0c94004865c089d8c89bdd566ad747 . Saya tidak tahu C ++ jadi mungkin ada kesalahan, tetapi intinya adalah membuat antarmuka yang diperluas oleh delegasi V2. Antarmuka ini dapat diambil dari delegasi menggunakan header C ++ terpisah (delegate_core.h) sehingga delegasi tingkat tinggi masih menjadi kotak hitam.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat