-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Webgl support #5
base: to-onnxruntime-web-webgl
Are you sure you want to change the base?
Conversation
おおー!! conv1dがないの、歴史を感じました。 ( |
すみません8e0f194以降はなぜかバグってるのでもうしばらくお待ちください |
これ、バグってたのは今までの方で、最新のコミットでは別の理由で落ちてるっぽいです。 |
chromeのハードウェアアクセラレーションを切ると真っ暗になる現象は無くなりましたが、エラー落ちするのは変わりませんでした |
エラーを貼ります (改行/インデントは自分で足しました) failed to inference ONNX model: Error: Failed to compile shader: Shader source:
# version 300 es
precision highp float;
precision highp int;
precision highp sampler2D;
in vec2 TexCoords;
out vec4 outputColor;
const vec2 halfCR = vec2(0.5, 0.5);
// Custom vector types to handle higher dimenalities.
struct ivec5 {
int x;
int y;
int z;
int w;
int u;
};
struct ivec6 {
int x;
int y;
int z;
int w;
int u;
int v;
};
int imod(int x, int y) {
return x - y * (x / y);
}
uniform sampler2D X;
int coordsToOffset(vec2 coords, int width, int height) {
float s = coords.s * float(width);
float t = coords.t * float(height);
int offset = int(t) * width + int(s);
return offset;
}
void toVec(vec2 texCoords, out int c[4]) {
int offset = coordsToOffset(texCoords, 1582, 1581);
c[0] = offset / 2500608;
offset -= c[0] * 2500608;
c[1] = offset / 96;
offset -= c[1] * 96;
c[2] = offset / 96;
offset -= c[2] * 96;
c[3] = offset;
}
void toVec(int offset, out int c[4]) {
c[0] = offset / 2500608;
offset -= c[0] * 2500608;
c[1] = offset / 96;
offset -= c[1] * 96;
c[2] = offset / 96;
offset -= c[2] * 96;
c[3] = offset;
}
int indicesToOffset_X(int indices[4]) {
int offset = 0;
offset += indices[3] * 1;
offset += indices[2] * 1;
offset += indices[1] * 26048;
offset += indices[0] * 3334144;
return offset;
}
vec2 offsetToCoords(int offset, int width, int height) {
int t = offset / width;
int s = offset - t*width;
vec2 coords = (vec2(s,t) + vec2(0.5,0.5)) / vec2(width, height);
return coords;
}
highp float decode(highp vec4 rgba) {
return rgba.r;
}
float getColorAsFloat(vec4 color) {
return decode(color);
}
float _X(int m[4]) {
int offset = indicesToOffset_X(m);
vec2 coords = offsetToCoords(offset, 1826, 1826);
float value = getColorAsFloat(texture(X, coords));
return value;
}
const int XC = 128;
const int XH = 26048;
const int XW = 1;
const int KH = 3;
const int KW = 1;
const int dilationH = 5;
const int dilationW = 5;
const int strideH = 1;
const int strideW = 1;
const int padH = 5;
const int padW = 0;
const int KHKW = KH*KW;
const int XCKHKW = XC * KHKW;
const int outputChannels = 4;
vec4 process(int indices[4]) {
int b = indices[0];
// batch size
int oh = indices[1] * strideH - padH;
//output height
int ow = indices[2] * strideW - padW;
//output width
int p = indices[3] * outputChannels;
//patch
vec4 value = vec4(0.0);
for(int i=0; i < outputChannels; ++i) {
if(p < XCKHKW) {
int patchC = p / KHKW;
int patchH = (p - patchC*KHKW) / KW;
int patchW = (p - patchC*KHKW) - patchH * KW;
int xh2 = oh + patchH * dilationH;
int xw2 = ow + patchW * dilationW;
int x[4];
x[0] = b;
x[1] = patchC;
x[2] = xh2;
x[3] = xw2;
if(xh2 >= 0 && xh2 < XH && xw2 >= 0 && xw2 < XW) {
value[i] = _X(x);
}
}
++p;
}
return value;
}
void main() {
int indices[4];
toVec(TexCoords, indices);
vec4 result = vec4(process(indices));
outputColor = result;
} |
上記のスクリプトを手元でコンパイルしてみましたが正常なコードでした。
というエラーが起こっているので、 |
十中八九メモリ不足っぽいです。僕のノートPC(内臓GPU)ではまともに動きませんでした。 |
動かしてみました!!動きました!!! メモリ8GBのRTX3070で動かしてみたのですが、同じくlengthを短くしないとメモリが溢れて挙動が変になりました。(VRAMの解放にchromeの再起動が必要だった) length=200で試したところ、メモリを6GBほど使って、1.4秒ほどかけて生成できました。 たしかlength=256で音声1秒なので、RTFは1.5とかそれくらいになりそうです。 ・・・・・・いやーーーなんかさすがにパフォーマンスが出てなさすぎる気がする・・・!! 📝 lengthを200にするコード const length = 200;
const phoneme_size = 45;
const speaker_id_data = BigInt64Array.from([1].map((x) => BigInt(x)));
const _f0_data = f0_data.slice(0, length);
const _phoneme_data = phoneme_data.slice(0, length * phoneme_size);
const f0 = new ort.Tensor("float32", _f0_data, [length, 1]);
const phoneme = new ort.Tensor("float32", _phoneme_data, [
length,
phoneme_size,
]); |
うーん何とも言えませんね... |
すみません、コメントしたつもりになっていました 🙇 #4 (comment) にもかいたのですが、数万×1の行列を数百×数百くらいにreshapeすれば動作が安定する・・・かも・・・。 |
なんか今更ですが、onnxruntime-webを1.18.0に上げてwebgpuに変更すると動きました(hifiganをwasm->webgpuにすると7倍高速化 on RTX3060) https://github.com/Yosshi999/vv_check_web/tree/webgl-wip |
@Yosshi999 お久しぶりです!コメントありがとうございます、ありがたいです!!! 7倍高速・・・ということは、以前のコメント見るとRTFが1.5くらいだったので、環境によっては0.2~0.3くらいになる・・・という感じでしょうか。 お手数おかけしてしまうのですが、もしよかったら速度測定をお願いできませんか 🙇 また現状では暗号化の観点からonnxの配布はしていませんが、暗号部分をonnxruntimeに埋め込んでweb版をビルドする方法もあると思うので、進展があれば結構面白いことも射程範囲に入るんじゃないかな~~と期待してたりします!!! |
すみません、全体を計測するのはだいぶ大変なので、decode部分(sosoa + hifigan)のみを計測しました 表にまとめると以下のようになります
|
あっすみません、decode部分だけで大丈夫です!ここが一番時間かかってるはずなので! おーーーー全く問題ない程度に早いですね!!! というのもpytorchとかはCUDAの計算が非同期に行われているので、CUDAの計算終了と関数が終了するタイミングがずれているんですよね。 もし間違いなさそうであれば、全く問題ない動作速度ですね!!!!! ちょっと一旦ご確認までコメントということで 🙇 |
decodeモデルを二つに分割し、hifiganの方のみをwebgl backendのonnxruntime-webに対応させる
関連: #4
適用したワークアラウンド一覧
Note
この変更をmainに適用する際にはvoicevox_coreに対して改修が必要になります。decode.onnxが消え新しく二つのonnxモデルができたので、これらを替わりにバイナリに埋め込む必要があります。