mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-02-02 16:23:58 +03:00
WIP:improve model selector
This commit is contained in:
parent
426388872a
commit
ff82ae986b
156
client/demo/dist/index.js
vendored
156
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -4,7 +4,6 @@ import { Title, TitleProps } from "./components/101_Title"
|
|||||||
import { StartButtonRow, StartButtonRowProps } from "./components/201_StartButtonRow"
|
import { StartButtonRow, StartButtonRowProps } from "./components/201_StartButtonRow"
|
||||||
import { PerformanceRow, PerformanceRowProps } from "./components/202_PerformanceRow"
|
import { PerformanceRow, PerformanceRowProps } from "./components/202_PerformanceRow"
|
||||||
import { ServerInfoRow, ServerInfoRowProps } from "./components/203_ServerInfoRow"
|
import { ServerInfoRow, ServerInfoRowProps } from "./components/203_ServerInfoRow"
|
||||||
import { ModelUploaderRow, ModelUploaderRowProps } from "./components/301_ModelUploaderRow"
|
|
||||||
import { FrameworkRow, FrameworkRowProps } from "./components/302_FrameworkRow"
|
import { FrameworkRow, FrameworkRowProps } from "./components/302_FrameworkRow"
|
||||||
import { AudioInputRow, AudioInputRowProps } from "./components/401_AudioInputRow"
|
import { AudioInputRow, AudioInputRowProps } from "./components/401_AudioInputRow"
|
||||||
import { AudioOutputRow, AudioOutputRowProps } from "./components/402_AudioOutputRow"
|
import { AudioOutputRow, AudioOutputRowProps } from "./components/402_AudioOutputRow"
|
||||||
@ -83,8 +82,6 @@ const initialize = () => {
|
|||||||
addToCatalog("onnxExecutor", (props: ONNXExecutorRowProps) => { return <ONNXExecutorRow {...props} /> })
|
addToCatalog("onnxExecutor", (props: ONNXExecutorRowProps) => { return <ONNXExecutorRow {...props} /> })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addToCatalog("modelUploader", (props: ModelUploaderRowProps) => { return <ModelUploaderRow {...props} /> })
|
|
||||||
addToCatalog("modelUploaderv2", (props: ModelUploaderRowv2Props) => { return <ModelUploaderRowv2 {...props} /> })
|
addToCatalog("modelUploaderv2", (props: ModelUploaderRowv2Props) => { return <ModelUploaderRowv2 {...props} /> })
|
||||||
addToCatalog("framework", (props: FrameworkRowProps) => { return <FrameworkRow {...props} /> })
|
addToCatalog("framework", (props: FrameworkRowProps) => { return <FrameworkRow {...props} /> })
|
||||||
addToCatalog("modelSamplingRate", (props: ModelSamplingRateRowProps) => { return <ModelSamplingRateRow {...props} /> })
|
addToCatalog("modelSamplingRate", (props: ModelSamplingRateRowProps) => { return <ModelSamplingRateRow {...props} /> })
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const ConfigSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
const configSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const configFilenameText = appState.serverSetting.fileUploadSettings[slot]?.configFile?.filename || appState.serverSetting.fileUploadSettings[slot]?.configFile?.file?.name || ""
|
|
||||||
const onConfigFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".json") == false && file.name.endsWith(".yaml") == false) {
|
|
||||||
alert("モデルファイルの拡張子はjsonである必要があります。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
configFile: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const onConfigFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
configFile: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Config(.json)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{configFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onConfigFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onConfigFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return configSelectRow
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
|
|
||||||
export const ModelSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
|
|
||||||
const onnxSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
|
|
||||||
if (!fileUploadSetting) {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
const onnxModelFilenameText = fileUploadSetting.onnxModel?.filename || fileUploadSetting.onnxModel?.file?.name || ""
|
|
||||||
const pyTorchFilenameText = fileUploadSetting.pyTorchModel?.filename || fileUploadSetting.pyTorchModel?.file?.name || ""
|
|
||||||
const modelFilenameText = onnxModelFilenameText + pyTorchFilenameText
|
|
||||||
|
|
||||||
const onModelFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".onnx") == false && file.name.endsWith(".pth") == false) {
|
|
||||||
alert("モデルファイルの拡張子は.onnxか.pthである必要があります。(Extension of the model file should be .onnx or .pth.)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (file.name.endsWith(".onnx") == true) {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
onnxModel: {
|
|
||||||
file: file
|
|
||||||
},
|
|
||||||
pyTorchModel: null
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (file.name.endsWith(".pth") == true) {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
pyTorchModel: {
|
|
||||||
file: file
|
|
||||||
},
|
|
||||||
onnxModel: null
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const onModelFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
onnxModel: null,
|
|
||||||
pyTorchModel: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Model(.onnx or .pth)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{modelFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onModelFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onModelFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return onnxSelectRow
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
type ONNXSelectRowProps = {
|
|
||||||
onlyWhenSelected: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ONNXSelectRow = (props: ONNXSelectRowProps) => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
|
|
||||||
const onnxSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
if (props.onlyWhenSelected && appState.serverSetting.fileUploadSettings[slot]?.framework != "ONNX") {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
const onnxModelFilenameText = appState.serverSetting.fileUploadSettings[slot]?.onnxModel?.filename || appState.serverSetting.fileUploadSettings[slot]?.onnxModel?.file?.name || ""
|
|
||||||
const onOnnxFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".onnx") == false) {
|
|
||||||
alert("モデルファイルの拡張子はonnxである必要があります。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
onnxModel: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const onOnnxFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
onnxModel: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Onnx(.onnx)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{onnxModelFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onOnnxFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onOnnxFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return onnxSelectRow
|
|
||||||
}
|
|
@ -1,61 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export type PyTorchSelectRowProps = {
|
|
||||||
onlyWhenSelected: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const PyTorchSelectRow = (props: PyTorchSelectRowProps) => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
const pyTorchSelectRow = useMemo(() => {
|
|
||||||
if (guiState.showPyTorchModelUpload == false) {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
if (props.onlyWhenSelected && appState.serverSetting.fileUploadSettings[slot]?.framework != "PyTorch") {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const pyTorchFilenameText = appState.serverSetting.fileUploadSettings[slot]?.pyTorchModel?.filename || appState.serverSetting.fileUploadSettings[slot]?.pyTorchModel?.file?.name || ""
|
|
||||||
const onPyTorchFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".pth") == false) {
|
|
||||||
alert("モデルファイルの拡張子はpthである必要があります。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
pyTorchModel: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const onPyTorchFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
pyTorchModel: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">PyTorch(.pth)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{pyTorchFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onPyTorchFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onPyTorchFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [guiState.showPyTorchModelUpload, appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, appState.serverSetting.serverSetting, appState.serverSetting.updateServerSettings, guiState.isConverting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return pyTorchSelectRow
|
|
||||||
}
|
|
@ -1,53 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector, Correspondence } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
|
|
||||||
export const CorrespondenceSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
|
|
||||||
const CorrespondenceSelectRow = useMemo(() => {
|
|
||||||
const correspondenceFileText = appState.clientSetting.clientSetting.correspondences ? JSON.stringify(appState.clientSetting.clientSetting.correspondences.map(x => { return x.dirname })) : ""
|
|
||||||
const onCorrespondenceFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
|
|
||||||
const correspondenceText = await file.text()
|
|
||||||
const cors = correspondenceText.split("\n").map(line => {
|
|
||||||
const items = line.split("|")
|
|
||||||
if (items.length != 3) {
|
|
||||||
console.warn("Invalid Correspondence Line:", line)
|
|
||||||
return null
|
|
||||||
} else {
|
|
||||||
const cor: Correspondence = {
|
|
||||||
sid: Number(items[0]),
|
|
||||||
correspondence: Number(items[1]),
|
|
||||||
dirname: items[2]
|
|
||||||
}
|
|
||||||
return cor
|
|
||||||
}
|
|
||||||
}).filter(x => { return x != null }) as Correspondence[]
|
|
||||||
console.log("recogninzed corresponding lines:", cors)
|
|
||||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: cors })
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const onCorrespondenceFileClearClicked = () => {
|
|
||||||
appState.clientSetting.updateClientSetting({ ...appState.clientSetting.clientSetting, correspondences: [] })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Correspondence</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{correspondenceFileText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onCorrespondenceFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onCorrespondenceFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.clientSetting.clientSetting, appState.clientSetting.updateClientSetting])
|
|
||||||
|
|
||||||
return CorrespondenceSelectRow
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
|
|
||||||
export const PyTorchClusterSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
|
|
||||||
const pyTorchSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const clusterModelFilenameText = appState.serverSetting.fileUploadSettings[slot]?.clusterTorchModel?.filename || appState.serverSetting.fileUploadSettings[slot]?.clusterTorchModel?.file?.name || ""
|
|
||||||
const onClusterFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".pt") == false) {
|
|
||||||
alert("モデルファイルの拡張子はptである必要があります。")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
clusterTorchModel: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onClusterFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
clusterTorchModel: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">cluster(.pt)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{clusterModelFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onClusterFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onClusterFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return pyTorchSelectRow
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
|
|
||||||
export const FeatureSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
|
|
||||||
const featureSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const featureFilenameText = appState.serverSetting.fileUploadSettings[slot]?.feature?.filename || appState.serverSetting.fileUploadSettings[slot]?.feature?.file?.name || ""
|
|
||||||
const onFeatureFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".npy") == false) {
|
|
||||||
alert("Feature file's extension should be npy")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
feature: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onFeatureFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
feature: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">feature(.npy)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{featureFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onFeatureFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onFeatureFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return featureSelectRow
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { fileSelector } from "@dannadori/voice-changer-client-js"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
|
|
||||||
export const IndexSelectRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
|
|
||||||
const indexSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const indexFilenameText = appState.serverSetting.fileUploadSettings[slot]?.index?.filename || appState.serverSetting.fileUploadSettings[slot]?.index?.file?.name || ""
|
|
||||||
const onIndexFileLoadClicked = async () => {
|
|
||||||
const file = await fileSelector("")
|
|
||||||
if (file.name.endsWith(".index") == false) {
|
|
||||||
alert("Index file's extension should be .index")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
index: {
|
|
||||||
file: file
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onIndexFileClearClicked = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
index: null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">index(.index)</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div>{indexFilenameText}</div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className="body-button" onClick={onIndexFileLoadClicked}>select</div>
|
|
||||||
<div className="body-button left-margin-1" onClick={onIndexFileClearClicked}>clear</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return indexSelectRow
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
|
|
||||||
export const HalfPrecisionRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
|
|
||||||
const halfPrecisionSelectRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
|
|
||||||
if (!fileUploadSetting) {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
const currentValue = fileUploadSetting ? fileUploadSetting.isHalf : true
|
|
||||||
const onHalfPrecisionChanged = () => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
isHalf: !appState.serverSetting.fileUploadSettings[slot].isHalf
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">-</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<input type="checkbox" checked={currentValue} onChange={() => onHalfPrecisionChanged()} /> half-precision
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return halfPrecisionSelectRow
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const ModelUploadButtonRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
const modelUploadButtonRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const onModelUploadClicked = async () => {
|
|
||||||
appState.serverSetting.loadModel(slot)
|
|
||||||
}
|
|
||||||
|
|
||||||
const uploadButtonClassName = appState.serverSetting.isUploading ? "body-button-disabled" : "body-button"
|
|
||||||
const uploadButtonAction = appState.serverSetting.isUploading ? () => { } : onModelUploadClicked
|
|
||||||
const uploadButtonLabel = appState.serverSetting.isUploading ? "wait..." : "upload"
|
|
||||||
const uploadingStatus = appState.serverSetting.isUploading ?
|
|
||||||
appState.serverSetting.uploadProgress == 0 ? `loading model...(wait about 20sec)` : `uploading.... ${appState.serverSetting.uploadProgress.toFixed(1)}%` : ""
|
|
||||||
|
|
||||||
|
|
||||||
const uploadedText = appState.serverSetting.fileUploadSettings[slot] == undefined ? "" : appState.serverSetting.fileUploadSettings[slot].uploaded ? "" : "not uploaded"
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2"></div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
{uploadingStatus}
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
<div className={uploadButtonClassName} onClick={uploadButtonAction}>{uploadButtonLabel}</div>
|
|
||||||
<div className="body-item-text-em" >{uploadedText}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.isUploading, appState.serverSetting.uploadProgress, appState.serverSetting.loadModel, guiState.modelSlotNum, appState.serverSetting.fileUploadSettings])
|
|
||||||
|
|
||||||
return modelUploadButtonRow
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { MAX_MODEL_SLOT_NUM } from "@dannadori/voice-changer-client-js"
|
|
||||||
import React, { useMemo } from "react"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const ModelSlotRow = () => {
|
|
||||||
const guiState = useGuiState()
|
|
||||||
const modelSlotRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const onModelSlotChanged = (val: number) => {
|
|
||||||
guiState.setModelSlotNum(val)
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Model Slot</div>
|
|
||||||
<div className="body-input-container">
|
|
||||||
<select value={slot} onChange={(e) => { onModelSlotChanged(Number(e.target.value)) }}>
|
|
||||||
{Array(MAX_MODEL_SLOT_NUM).fill(0).map((_x, index) => {
|
|
||||||
return <option key={index} value={index} >{index}</option>
|
|
||||||
})}
|
|
||||||
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return modelSlotRow
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const DescriptionRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
const descriptionRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Model Desc.</div>
|
|
||||||
<div className="body-input-container">
|
|
||||||
Tuning: {fileUploadSetting?.defaultTune || 0}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return descriptionRow
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
import React, { useMemo } from "react"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const DefaultTuneRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
const defaultTuneRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
|
|
||||||
if (!fileUploadSetting) {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
const currentValue = fileUploadSetting.defaultTune
|
|
||||||
|
|
||||||
const onDefaultTuneChanged = (val: number) => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
defaultTune: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-2-1-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2 ">Default Tune</div>
|
|
||||||
<div>
|
|
||||||
<input type="range" className="body-item-input-slider" min="-50" max="50" step="1" value={currentValue} onChange={(e) => {
|
|
||||||
onDefaultTuneChanged(Number(e.target.value))
|
|
||||||
}}></input>
|
|
||||||
<span className="body-item-input-slider-val">{currentValue}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
</div>
|
|
||||||
<div className="body-button-container">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return defaultTuneRow
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
import { Framework } from "@dannadori/voice-changer-client-js"
|
|
||||||
import React, { useMemo } from "react"
|
|
||||||
import { useAppState } from "../../../001_provider/001_AppStateProvider"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
|
|
||||||
export const FrameworkSelectorRow = () => {
|
|
||||||
const appState = useAppState()
|
|
||||||
const guiState = useGuiState()
|
|
||||||
const frameworkSelectorRow = useMemo(() => {
|
|
||||||
const slot = guiState.modelSlotNum
|
|
||||||
const fileUploadSetting = appState.serverSetting.fileUploadSettings[slot]
|
|
||||||
const currentValue = fileUploadSetting?.framework || Framework.PyTorch
|
|
||||||
|
|
||||||
const onFrameworkChanged = (val: Framework) => {
|
|
||||||
appState.serverSetting.setFileUploadSetting(slot, {
|
|
||||||
...appState.serverSetting.fileUploadSettings[slot],
|
|
||||||
framework: val
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return (
|
|
||||||
<div className="body-row split-3-7 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-2">Framework</div>
|
|
||||||
<div className="body-input-container">
|
|
||||||
<div className="body-select-container">
|
|
||||||
<select className="body-select" value={currentValue} onChange={(e) => {
|
|
||||||
onFrameworkChanged(e.target.value as Framework)
|
|
||||||
}}>
|
|
||||||
{
|
|
||||||
Object.values(Framework).map(x => {
|
|
||||||
return <option key={x} value={x}>{x}</option>
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}, [appState.serverSetting.fileUploadSettings, appState.serverSetting.setFileUploadSetting, guiState.modelSlotNum])
|
|
||||||
|
|
||||||
return frameworkSelectorRow
|
|
||||||
}
|
|
@ -1,88 +0,0 @@
|
|||||||
import React, { useMemo, useEffect } from "react"
|
|
||||||
import { useGuiState } from "../001_GuiStateProvider"
|
|
||||||
import { ConfigSelectRow } from "./301-1_ConfigSelectRow"
|
|
||||||
import { ModelSelectRow } from "./301-2-5_ModelSelectRow"
|
|
||||||
import { ONNXSelectRow } from "./301-2_ONNXSelectRow"
|
|
||||||
import { PyTorchSelectRow } from "./301-3_PyTorchSelectRow"
|
|
||||||
import { CorrespondenceSelectRow } from "./301-4_CorrespondenceSelectRow"
|
|
||||||
import { PyTorchClusterSelectRow } from "./301-5_PyTorchClusterSelectRow"
|
|
||||||
import { FeatureSelectRow } from "./301-6_FeatureSelectRow"
|
|
||||||
import { IndexSelectRow } from "./301-7_IndexSelectRow"
|
|
||||||
import { HalfPrecisionRow } from "./301-8_HalfPrescisionRow"
|
|
||||||
import { ModelUploadButtonRow } from "./301-9_ModelUploadButtonRow"
|
|
||||||
import { ModelSlotRow } from "./301-a_ModelSlotRow"
|
|
||||||
import { DefaultTuneRow } from "./301-c_DefaultTuneRow"
|
|
||||||
import { FrameworkSelectorRow } from "./301-d_FrameworkSelector"
|
|
||||||
|
|
||||||
export type ModelUploaderRowProps = {
|
|
||||||
showModelSlot: boolean
|
|
||||||
showFrameworkSelector: boolean
|
|
||||||
showConfig: boolean
|
|
||||||
showOnnx: boolean
|
|
||||||
showPyTorch: boolean
|
|
||||||
showCorrespondence: boolean
|
|
||||||
showPyTorchCluster: boolean
|
|
||||||
|
|
||||||
showFeature: boolean
|
|
||||||
showIndex: boolean
|
|
||||||
showHalfPrecision: boolean
|
|
||||||
showDescription: boolean
|
|
||||||
showDefaultTune: boolean
|
|
||||||
|
|
||||||
showPyTorchEnableCheckBox: boolean
|
|
||||||
defaultEnablePyTorch: boolean
|
|
||||||
onlySelectedFramework: boolean
|
|
||||||
oneModelFileType: boolean
|
|
||||||
|
|
||||||
showOnnxExportButton: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
export const ModelUploaderRow = (props: ModelUploaderRowProps) => {
|
|
||||||
const guiState = useGuiState()
|
|
||||||
useEffect(() => {
|
|
||||||
guiState.setShowPyTorchModelUpload(props.defaultEnablePyTorch)
|
|
||||||
}, [])
|
|
||||||
|
|
||||||
const modelUploaderRow = useMemo(() => {
|
|
||||||
const pytorchEnableCheckBox = props.showPyTorchEnableCheckBox ?
|
|
||||||
<div>
|
|
||||||
<input type="checkbox" checked={guiState.showPyTorchModelUpload} onChange={(e) => {
|
|
||||||
guiState.setShowPyTorchModelUpload(e.target.checked)
|
|
||||||
}} /> enable PyTorch
|
|
||||||
</div>
|
|
||||||
:
|
|
||||||
<></>
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="body-row split-3-3-4 left-padding-1 guided">
|
|
||||||
<div className="body-item-title left-padding-1">Model Uploader</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
<div></div>
|
|
||||||
</div>
|
|
||||||
<div className="body-item-text">
|
|
||||||
{pytorchEnableCheckBox}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{props.showModelSlot ? <ModelSlotRow /> : <></>}
|
|
||||||
{props.showFrameworkSelector ? <FrameworkSelectorRow /> : <></>}
|
|
||||||
{props.showConfig ? <ConfigSelectRow /> : <></>}
|
|
||||||
|
|
||||||
{props.oneModelFileType ? <ModelSelectRow /> : <></>}
|
|
||||||
{props.showOnnx ? <ONNXSelectRow onlyWhenSelected={props.onlySelectedFramework} /> : <></>}
|
|
||||||
{props.showPyTorch ? <PyTorchSelectRow onlyWhenSelected={props.onlySelectedFramework} /> : <></>}
|
|
||||||
|
|
||||||
{props.showCorrespondence ? <CorrespondenceSelectRow /> : <></>}
|
|
||||||
{props.showPyTorchCluster ? <PyTorchClusterSelectRow /> : <></>}
|
|
||||||
{props.showFeature ? <FeatureSelectRow /> : <></>}
|
|
||||||
{props.showIndex ? <IndexSelectRow /> : <></>}
|
|
||||||
{props.showHalfPrecision ? <HalfPrecisionRow /> : <></>}
|
|
||||||
{props.showDefaultTune ? <DefaultTuneRow /> : <></>}
|
|
||||||
|
|
||||||
<ModelUploadButtonRow />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}, [guiState.showPyTorchModelUpload])
|
|
||||||
|
|
||||||
return modelUploaderRow
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user