mirror of
https://github.com/neodyland/sbv2-api.git
synced 2025-12-28 01:52:59 +00:00
111
Cargo.lock
generated
111
Cargo.lock
generated
@@ -802,6 +802,12 @@ dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indoc"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5"
|
||||
|
||||
[[package]]
|
||||
name = "instant"
|
||||
version = "0.1.13"
|
||||
@@ -1213,6 +1219,15 @@ version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@@ -1375,7 +1390,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ort"
|
||||
version = "2.0.0-rc.6"
|
||||
source = "git+https://github.com/pykeio/ort.git#ee5cc2046c346b8e6f71ce543c1f6d31702337de"
|
||||
source = "git+https://github.com/pykeio/ort.git#7ad5b84e5a42cb6399635d95d88fc81aa38fddf3"
|
||||
dependencies = [
|
||||
"half",
|
||||
"libloading",
|
||||
@@ -1387,7 +1402,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ort-sys"
|
||||
version = "2.0.0-rc.6"
|
||||
source = "git+https://github.com/pykeio/ort.git#ee5cc2046c346b8e6f71ce543c1f6d31702337de"
|
||||
source = "git+https://github.com/pykeio/ort.git#7ad5b84e5a42cb6399635d95d88fc81aa38fddf3"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"pkg-config",
|
||||
@@ -1544,6 +1559,70 @@ dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "831e8e819a138c36e212f3af3fd9eeffed6bf1510a805af35b0edee5ffa59433"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"indoc",
|
||||
"libc",
|
||||
"memoffset",
|
||||
"once_cell",
|
||||
"portable-atomic",
|
||||
"pyo3-build-config",
|
||||
"pyo3-ffi",
|
||||
"pyo3-macros",
|
||||
"unindent",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-build-config"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e8730e591b14492a8945cdff32f089250b05f5accecf74aeddf9e8272ce1fa8"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-ffi"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e97e919d2df92eb88ca80a037969f44e5e70356559654962cbb3316d00300c6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"pyo3-build-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb57983022ad41f9e683a599f2fd13c3664d7063a3ac5714cae4b7bee7d3f206"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"pyo3-macros-backend",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyo3-macros-backend"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec480c0c51ddec81019531705acac51bcdbeae563557c982aa8263bb96880372"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"pyo3-build-config",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
@@ -1750,9 +1829,19 @@ dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sbv2_bindings"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"ndarray",
|
||||
"pyo3",
|
||||
"sbv2_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sbv2_core"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"dotenvy",
|
||||
@@ -1977,6 +2066,12 @@ dependencies = [
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
@@ -2135,9 +2230,9 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-normalization"
|
||||
@@ -2175,6 +2270,12 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||
|
||||
[[package]]
|
||||
name = "unindent"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce"
|
||||
|
||||
[[package]]
|
||||
name = "untrusted"
|
||||
version = "0.9.0"
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["sbv2_api", "sbv2_core"]
|
||||
members = ["sbv2_api", "sbv2_core", "sbv2_bindings"]
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0.86"
|
||||
dotenvy = "0.15.7"
|
||||
env_logger = "0.11.5"
|
||||
ndarray = "0.16.1"
|
||||
169
sbv2_bindings/.github/workflows/CI.yml
vendored
Normal file
169
sbv2_bindings/.github/workflows/CI.yml
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
# This file is autogenerated by maturin v1.7.1
|
||||
# To update, run
|
||||
#
|
||||
# maturin generate-ci github
|
||||
#
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
tags:
|
||||
- '*'
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
linux:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- runner: ubuntu-latest
|
||||
target: x86_64
|
||||
- runner: ubuntu-latest
|
||||
target: x86
|
||||
- runner: ubuntu-latest
|
||||
target: aarch64
|
||||
- runner: ubuntu-latest
|
||||
target: armv7
|
||||
- runner: ubuntu-latest
|
||||
target: s390x
|
||||
- runner: ubuntu-latest
|
||||
target: ppc64le
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
manylinux: auto
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-linux-${{ matrix.platform.target }}
|
||||
path: dist
|
||||
|
||||
musllinux:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- runner: ubuntu-latest
|
||||
target: x86_64
|
||||
- runner: ubuntu-latest
|
||||
target: x86
|
||||
- runner: ubuntu-latest
|
||||
target: aarch64
|
||||
- runner: ubuntu-latest
|
||||
target: armv7
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
manylinux: musllinux_1_2
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-musllinux-${{ matrix.platform.target }}
|
||||
path: dist
|
||||
|
||||
windows:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- runner: windows-latest
|
||||
target: x64
|
||||
- runner: windows-latest
|
||||
target: x86
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
architecture: ${{ matrix.platform.target }}
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-windows-${{ matrix.platform.target }}
|
||||
path: dist
|
||||
|
||||
macos:
|
||||
runs-on: ${{ matrix.platform.runner }}
|
||||
strategy:
|
||||
matrix:
|
||||
platform:
|
||||
- runner: macos-12
|
||||
target: x86_64
|
||||
- runner: macos-14
|
||||
target: aarch64
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
args: --release --out dist --find-interpreter
|
||||
sccache: 'true'
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-macos-${{ matrix.platform.target }}
|
||||
path: dist
|
||||
|
||||
sdist:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build sdist
|
||||
uses: PyO3/maturin-action@v1
|
||||
with:
|
||||
command: sdist
|
||||
args: --out dist
|
||||
- name: Upload sdist
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wheels-sdist
|
||||
path: dist
|
||||
|
||||
release:
|
||||
name: Release
|
||||
runs-on: ubuntu-latest
|
||||
if: "startsWith(github.ref, 'refs/tags/')"
|
||||
needs: [linux, musllinux, windows, macos, sdist]
|
||||
steps:
|
||||
- uses: actions/download-artifact@v4
|
||||
- name: Publish to PyPI
|
||||
uses: PyO3/maturin-action@v1
|
||||
env:
|
||||
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
|
||||
with:
|
||||
command: upload
|
||||
args: --non-interactive --skip-existing wheels-*/*
|
||||
15
sbv2_bindings/Cargo.toml
Normal file
15
sbv2_bindings/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[package]
|
||||
name = "sbv2_bindings"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
[lib]
|
||||
name = "sbv2_bindings"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
ndarray.workspace = true
|
||||
pyo3 = { version = "0.22.0", features = ["anyhow"] }
|
||||
sbv2_core = { version = "0.1.0", path = "../sbv2_core" }
|
||||
18
sbv2_bindings/examples/basic.py
Normal file
18
sbv2_bindings/examples/basic.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from sbv2_bindings import TTSModel
|
||||
|
||||
|
||||
def main():
|
||||
print("Loading models...")
|
||||
model = TTSModel.from_path("../models/debert.onnx", "../models/tokenizer.json")
|
||||
print("Models loaded!")
|
||||
|
||||
model.load_sbv2file_from_path("amitaro", "../models/amitaro.sbv2")
|
||||
print("All setup is done!")
|
||||
|
||||
style_vector = model.get_style_vector("amitaro", 0, 1.0)
|
||||
with open("output.wav", "wb") as f:
|
||||
f.write(model.synthesize("おはようございます。", "amitaro", style_vector, 0.0, 0.5))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
15
sbv2_bindings/pyproject.toml
Normal file
15
sbv2_bindings/pyproject.toml
Normal file
@@ -0,0 +1,15 @@
|
||||
[build-system]
|
||||
requires = ["maturin>=1.7,<2.0"]
|
||||
build-backend = "maturin"
|
||||
|
||||
[project]
|
||||
name = "sbv2_bindings"
|
||||
requires-python = ">=3.8"
|
||||
classifiers = [
|
||||
"Programming Language :: Rust",
|
||||
"Programming Language :: Python :: Implementation :: CPython",
|
||||
"Programming Language :: Python :: Implementation :: PyPy",
|
||||
]
|
||||
dynamic = ["version"]
|
||||
[tool.maturin]
|
||||
features = ["pyo3/extension-module"]
|
||||
11
sbv2_bindings/src/lib.rs
Normal file
11
sbv2_bindings/src/lib.rs
Normal file
@@ -0,0 +1,11 @@
|
||||
use pyo3::prelude::*;
|
||||
mod sbv2;
|
||||
pub mod style;
|
||||
|
||||
/// sbv2 bindings module
|
||||
#[pymodule]
|
||||
fn sbv2_bindings(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
m.add_class::<sbv2::TTSModel>()?;
|
||||
m.add_class::<style::StyleVector>()?;
|
||||
Ok(())
|
||||
}
|
||||
145
sbv2_bindings/src/sbv2.rs
Normal file
145
sbv2_bindings/src/sbv2.rs
Normal file
@@ -0,0 +1,145 @@
|
||||
use pyo3::prelude::*;
|
||||
use pyo3::types::PyBytes;
|
||||
use sbv2_core::tts::TTSModelHolder;
|
||||
|
||||
use crate::style::StyleVector;
|
||||
|
||||
use std::fs;
|
||||
|
||||
/// TTSModel class
|
||||
///
|
||||
/// 音声合成するために使うクラス
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// bert_model_bytes : bytes
|
||||
/// BERTモデルのバイナリデータ
|
||||
/// tokenizer_bytes : bytes
|
||||
/// トークナイザーのバイナリデータ
|
||||
#[pyclass]
|
||||
pub struct TTSModel {
|
||||
pub model: TTSModelHolder,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl TTSModel {
|
||||
#[new]
|
||||
fn new(bert_model_bytes: Vec<u8>, tokenizer_bytes: Vec<u8>) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
model: TTSModelHolder::new(bert_model_bytes, tokenizer_bytes)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// パスからTTSModelインスタンスを生成する
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// bert_model_path : str
|
||||
/// BERTモデルのパス
|
||||
/// tokenizer_path : str
|
||||
/// トークナイザーのパス
|
||||
#[staticmethod]
|
||||
fn from_path(bert_model_path: String, tokenizer_path: String) -> anyhow::Result<Self> {
|
||||
Ok(Self {
|
||||
model: TTSModelHolder::new(fs::read(bert_model_path)?, fs::read(tokenizer_path)?)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// SBV2ファイルを読み込む
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// ident : str
|
||||
/// 識別子
|
||||
/// sbv2file_bytes : bytes
|
||||
/// SBV2ファイルのバイナリデータ
|
||||
fn load_sbv2file(&mut self, ident: String, sbv2file_bytes: Vec<u8>) -> anyhow::Result<()> {
|
||||
self.model.load_sbv2file(ident, sbv2file_bytes)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// パスからSBV2ファイルを読み込む
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// ident : str
|
||||
/// 識別子
|
||||
/// sbv2file_path : str
|
||||
/// SBV2ファイルのパス
|
||||
fn load_sbv2file_from_path(
|
||||
&mut self,
|
||||
ident: String,
|
||||
sbv2file_path: String,
|
||||
) -> anyhow::Result<()> {
|
||||
self.model.load_sbv2file(ident, fs::read(sbv2file_path)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// スタイルベクトルを取得する
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// ident : str
|
||||
/// 識別子
|
||||
/// style_id : int
|
||||
/// スタイルID
|
||||
/// weight : float
|
||||
/// 重み
|
||||
///
|
||||
/// Returns
|
||||
/// -------
|
||||
/// style_vector : StyleVector
|
||||
/// スタイルベクトル
|
||||
fn get_style_vector(
|
||||
&self,
|
||||
ident: String,
|
||||
style_id: i32,
|
||||
weight: f32,
|
||||
) -> anyhow::Result<StyleVector> {
|
||||
Ok(StyleVector::new(
|
||||
self.model.get_style_vector(ident, style_id, weight)?,
|
||||
))
|
||||
}
|
||||
|
||||
/// テキストから音声を合成する
|
||||
///
|
||||
/// Parameters
|
||||
/// ----------
|
||||
/// text : str
|
||||
/// テキスト
|
||||
/// ident : str
|
||||
/// 識別子
|
||||
/// style_vector : StyleVector
|
||||
/// スタイルベクトル
|
||||
/// sdp_ratio : float
|
||||
/// SDP比率
|
||||
/// length_scale : float
|
||||
/// 音声の長さのスケール
|
||||
///
|
||||
/// Returns
|
||||
/// -------
|
||||
/// voice_data : bytes
|
||||
/// 音声データ
|
||||
fn synthesize<'p>(
|
||||
&'p self,
|
||||
py: Python<'p>,
|
||||
text: String,
|
||||
ident: String,
|
||||
style_vector: StyleVector,
|
||||
sdp_ratio: f32,
|
||||
length_scale: f32,
|
||||
) -> anyhow::Result<Bound<PyBytes>> {
|
||||
let (bert_ori, phones, tones, lang_ids) = self.model.parse_text(&text)?;
|
||||
let data = self.model.synthesize(
|
||||
ident,
|
||||
bert_ori,
|
||||
phones,
|
||||
tones,
|
||||
lang_ids,
|
||||
style_vector.get(),
|
||||
sdp_ratio,
|
||||
length_scale,
|
||||
)?;
|
||||
Ok(PyBytes::new_bound(py, &data))
|
||||
}
|
||||
}
|
||||
19
sbv2_bindings/src/style.rs
Normal file
19
sbv2_bindings/src/style.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use ndarray::Array1;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
/// StyleVector class
|
||||
///
|
||||
/// スタイルベクトルを表すクラス
|
||||
#[pyclass]
|
||||
#[derive(Clone)]
|
||||
pub struct StyleVector(Array1<f32>);
|
||||
|
||||
impl StyleVector {
|
||||
pub fn new(data: Array1<f32>) -> Self {
|
||||
StyleVector(data)
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Array1<f32> {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
[package]
|
||||
name = "sbv2_core"
|
||||
description = "Style-Bert-VITSの推論ライブラリ"
|
||||
version = "0.1.1"
|
||||
version = "0.1.2"
|
||||
edition = "2021"
|
||||
license = "MIT"
|
||||
readme = "../README.md"
|
||||
repository = "https://github.com/tuna2134/sbv2-api"
|
||||
documentation = "https://docs.rs/sbv2_core"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
@@ -13,7 +14,7 @@ dotenvy.workspace = true
|
||||
env_logger.workspace = true
|
||||
hound = "3.5.1"
|
||||
jpreprocess = { version = "0.10.0", features = ["naist-jdic"] }
|
||||
ndarray = "0.16.1"
|
||||
ndarray.workspace = true
|
||||
num_cpus = "1.16.0"
|
||||
once_cell = "1.19.0"
|
||||
ort = { git = "https://github.com/pykeio/ort.git", version = "2.0.0-rc.6" }
|
||||
|
||||
Reference in New Issue
Block a user