• 車種別
  • パーツ
  • 整備手帳
  • ブログ
  • みんカラ+
.

狄雲@パーツ難民のブログ一覧

2026年07月22日 イイね!

Irodori-TTSに拠る音声生成 Radeon RX7800XT (2/2)

Irodori-TTSに拠る音声生成 Radeon RX7800XT (2/2)#プログラムの書き換え
decorators.py

import math
import os
import time
from collections import defaultdict
from functools import wraps

import torch
import torch.distributed as dist
from rich import box
from rich.console import Console
from rich.console import Group
from rich.live import Live
from rich.markdown import Markdown
from rich.padding import Padding
from rich.panel import Panel
from rich.progress import BarColumn
from rich.progress import Progress
from rich.progress import SpinnerColumn
from rich.progress import TimeElapsedColumn
from rich.progress import TimeRemainingColumn
from rich.rule import Rule
from rich.table import Table
from torch.utils.tensorboard import SummaryWriter


# This is here so that the history can be pickled.
def default_list():
return []


class Mean:
"""Keeps track of the running mean, along with the latest
value.
"""

def __init__(self):
self.reset()

def __call__(self):
mean = self.total / max(self.count, 1)
return mean

def reset(self):
self.count = 0
self.total = 0

def update(self, val):
if math.isfinite(val):
self.count += 1
self.total += val


def when(condition):
"""Runs a function only when the condition is met. The condition is
a function that is run.

Parameters
----------
condition : Callable
Function to run to check whether or not to run the decorated
function.

Example
-------
Checkpoint only runs every 100 iterations, and only if the
local rank is 0.

>>> i = 0
>>> rank = 0
>>>
>>> @when(lambda: i % 100 == 0 and rank == 0)
>>> def checkpoint():
>>> print("Saving to /runs/exp1")
>>>
>>> for i in range(1000):
>>> checkpoint()

"""

def decorator(fn):
@wraps(fn)
def decorated(*args, **kwargs):
if condition():
return fn(*args, **kwargs)

return decorated

return decorator


def timer(prefix: str = "time"):
"""Adds execution time to the output dictionary of the decorated
function. The function decorated by this must output a dictionary.
The key added will follow the form "[prefix]/[name_of_function]"

Parameters
----------
prefix : str, optional
The key added will follow the form "[prefix]/[name_of_function]",
by default "time".
"""

def decorator(fn):
@wraps(fn)
def decorated(*args, **kwargs):
s = time.perf_counter()
output = fn(*args, **kwargs)
assert isinstance(output, dict)
e = time.perf_counter()
output[f"{prefix}/{fn.__name__}"] = e - s
return output

return decorated

return decorator


class Tracker:
"""
A tracker class that helps to monitor the progress of training and logging the metrics.

Attributes
----------
metrics : dict
A dictionary containing the metrics for each label.
history : dict
A dictionary containing the history of metrics for each label.
writer : SummaryWriter
A SummaryWriter object for logging the metrics.
rank : int
The rank of the current process.
step : int
The current step of the training.
tasks : dict
A dictionary containing the progress bars and tables for each label.
pbar : Progress
A progress bar object for displaying the progress.
consoles : list
A list of console objects for logging.
live : Live
A Live object for updating the display live.

Methods
-------
print(msg: str)
Prints the given message to all consoles.
update(label: str, fn_name: str)
Updates the progress bar and table for the given label.
done(label: str, title: str)
Resets the progress bar and table for the given label and prints the final result.
track(label: str, length: int, completed: int = 0, op=getattr(dist, "ReduceOp", None) and dist.ReduceOp.AVG or None, ddp_active: bool = "LOCAL_RANK" in os.environ)
A decorator for tracking the progress and metrics of a function.
log(label: str, value_type: str = "value", history: bool = True)
A decorator for logging the metrics of a function.
is_best(label: str, key: str) -> bool
Checks if the latest value of the given key in the label is the best so far.
state_dict() -> dict
Returns a dictionary containing the state of the tracker.
load_state_dict(state_dict: dict) -> Tracker
Loads the state of the tracker from the given state dictionary.
"""

def __init__(
self,
writer: SummaryWriter = None,
log_file: str = None,
rank: int = 0,
console_width: int = 100,
step: int = 0,
):
"""
Initializes the Tracker object.

Parameters
----------
writer : SummaryWriter, optional
A SummaryWriter object for logging the metrics, by default None.
log_file : str, optional
The path to the log file, by default None.
rank : int, optional
The rank of the current process, by default 0.
console_width : int, optional
The width of the console, by default 100.
step : int, optional
The current step of the training, by default 0.
"""
self.metrics = {}
self.history = {}
self.writer = writer
self.rank = rank
self.step = step

# Create progress bars etc.
self.tasks = {}
self.pbar = Progress(
SpinnerColumn(),
"[progress.description]{task.description}",
"{task.completed}/{task.total}",
BarColumn(),
TimeElapsedColumn(),
"/",
TimeRemainingColumn(),
)
self.consoles = [Console(width=console_width)]
self.live = Live(console=self.consoles[0], refresh_per_second=10)
if log_file is not None:
self.consoles.append(Console(width=console_width, file=open(log_file, "a")))

def print(self, msg):
"""
Prints the given message to all consoles.

Parameters
----------
msg : str
The message to be printed.
"""
if self.rank == 0:
for c in self.consoles:
c.log(msg)

def update(self, label, fn_name):
"""
Updates the progress bar and table for the given label.

Parameters
----------
label : str
The label of the progress bar and table to be updated.
fn_name : str
The name of the function associated with the label.
"""
if self.rank == 0:
self.pbar.advance(self.tasks[label]["pbar"])

# Create table
table = Table(title=label, expand=True, box=box.MINIMAL)
table.add_column("key", style="cyan")
table.add_column("value", style="bright_blue")
table.add_column("mean", style="bright_green")

keys = self.metrics[label]["value"].keys()
for k in keys:
value = self.metrics[label]["value"][k]
mean = self.metrics[label]["mean"][k]()
table.add_row(k, f"{value:10.6f}", f"{mean:10.6f}")

self.tasks[label]["table"] = table
tables = [t["table"] for t in self.tasks.values()]
group = Group(*tables, self.pbar)
self.live.update(
Group(
Padding("", (0, 0)),
Rule(f"[italic]{fn_name}()", style="white"),
Padding("", (0, 0)),
Panel.fit(
group, padding=(0, 5), title="[b]Progress", border_style="blue"
),
)
)

def done(self, label: str, title: str):
"""
Resets the progress bar and table for the given label and prints the final result.

Parameters
----------
label : str
The label of the progress bar and table to be reset.
title : str
The title to be displayed when printing the final result.
"""
for label in self.metrics:
for v in self.metrics[label]["mean"].values():
v.reset()

if self.rank == 0:
self.pbar.reset(self.tasks[label]["pbar"])
tables = [t["table"] for t in self.tasks.values()]
group = Group(Markdown(f"# {title}"), *tables, self.pbar)
self.print(group)

def track(
self,
label: str,
length: int,
completed: int = 0,
op=getattr(dist, "ReduceOp", None) and dist.ReduceOp.AVG or None,
ddp_active: bool = "LOCAL_RANK" in os.environ,
):
"""
A decorator for tracking the progress and metrics of a function.

Parameters
----------
label : str
The label to be associated with the progress and metrics.
length : int
The total number of iterations to be completed.
completed : int, optional
The number of iterations already completed, by default 0.
op : optional
The reduce operation to be used.
ddp_active : bool, optional
Whether the DistributedDataParallel is active, by default "LOCAL_RANK" in os.environ.
"""
self.tasks[label] = {
"pbar": self.pbar.add_task(
f"[white]Iteration ({label})", total=length, completed=completed
),
"table": Table(),
}
self.metrics[label] = {
"value": defaultdict(),
"mean": defaultdict(lambda: Mean()),
}

def decorator(fn):
@wraps(fn)
def decorated(*args, **kwargs):
output = fn(*args, **kwargs)
if not isinstance(output, dict):
self.update(label, fn.__name__)
return output
# Collect across all DDP processes
scalar_keys = []
for k, v in output.items():
if isinstance(v, (int, float)):
v = torch.tensor([v])
if not torch.is_tensor(v):
continue
if ddp_active and v.is_cuda and op is not None: # pragma: no cover
dist.all_reduce(v, op=op)
output[k] = v.detach()
if torch.numel(v) == 1:
scalar_keys.append(k)
output[k] = v.item()

# Save the outputs to tracker
for k, v in output.items():
if k not in scalar_keys:
continue
self.metrics[label]["value"][k] = v
# Update the running mean
self.metrics[label]["mean"][k].update(v)

self.update(label, fn.__name__)
return output

return decorated

return decorator

def log(self, label: str, value_type: str = "value", history: bool = True):
"""
A decorator for logging the metrics of a function.

Parameters
----------
label : str
The label to be associated with the logging.
value_type : str, optional
The type of value to be logged, by default "value".
history : bool, optional
Whether to save the history of the metrics, by default True.
"""
assert value_type in ["mean", "value"]
if history:
if label not in self.history:
self.history[label] = defaultdict(default_list)

def decorator(fn):
@wraps(fn)
def decorated(*args, **kwargs):
output = fn(*args, **kwargs)
if self.rank == 0:
nonlocal value_type, label
metrics = self.metrics[label][value_type]
for k, v in metrics.items():
v = v() if isinstance(v, Mean) else v
if self.writer is not None:
self.writer.add_scalar(f"{k}/{label}", v, self.step)
if label in self.history:
self.history[label][k].append(v)

if label in self.history:
self.history[label]["step"].append(self.step)

return output

return decorated

return decorator

def is_best(self, label, key):
"""
Checks if the latest value of the given key in the label is the best so far.

Parameters
----------
label : str
The label of the metrics to be checked.
key : str
The key of the metric to be checked.

Returns
-------
bool
True if the latest value is the best so far, otherwise False.
"""
return self.history[label][key][-1] == min(self.history[label][key])

def state_dict(self):
"""
Returns a dictionary containing the state of the tracker.

Returns
-------
dict
A dictionary containing the history and step of the tracker.
"""
return {"history": self.history, "step": self.step}

def load_state_dict(self, state_dict):
"""
Loads the state of the tracker from the given state dictionary.

Parameters
----------
state_dict : dict
A dictionary containing the history and step of the tracker.

Returns
-------
Tracker
The tracker object with the loaded state.
"""
self.history = state_dict["history"]
self.step = state_dict["step"]
return self

ここまで出来たら生成ができるはず
Irodori-TTSの実行

PowerShellから次のコマンドを実行
uv run --no-sync python gradio_app.py --server-name 0.0.0.0 --server-port 7860

あとはブラウザで、localhost:7860か127.0.0.1:7860へアクセスする。
Posted at 2026/07/22 20:52:36 | コメント(0) | トラックバック(0) | PC | 日記
2026年07月22日 イイね!

Irodori-TTSに拠る音声生成 Radeon RX7800XT (1/2)

Irodori-TTSに拠る音声生成 Radeon RX7800XT (1/2)rocm7.2.1での音声生成にやっと成功。

出来た事
 WEB-UI
  テキストの音声生成
  参照音声を利用したテキストの音声生成


問題点
 生成した音声に「電子透かし」を入れられない

今後の予定
 特定人物のサンプル音声からの生成
 ※Rocm6.1では成功している

RTX2000シリーズ以降やCPUで実行する人には関係のない苦労です。
TRX5050あたりを買った方が安く簡単に生成できます。
いいんだよ!やってみたかったんだよ!

ここから覚書
Irodori-TTSをインストールしたいフォルダで、右クリックメニューからPowerShellを開く
以下のコマンドを順次実行
#は何をするかのメモなので実行しなくてもよい

#PowerShellの一時的なセキュリティ解除
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process

#Irodori-TTSのインストール
git clone https://github.com/Aratako/Irodori-TTS.git

#仮想環境のセットアップ
python3.12 -m venv .venv
.venv\Scripts\activate

#PythonのVersionを確認
#3.12.nnと表示されていればOK
python --version

#ROCm環境をセットアップする
pip install --no-cache-dir `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/rocm_sdk_core-7.2.1-py3-none-win_amd64.whl `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/rocm_sdk_devel-7.2.1-py3-none-win_amd64.whl `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/rocm_sdk_libraries_custom-7.2.1-py3-none-win_amd64.whl `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/rocm-7.2.1.tar.gz

#ROCm AMD GPU用のtorch、torchaudioをインストール
pip install --no-cache-dir `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/torch-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl `
https://repo.radeon.com/rocm/windows/rocm-rel-7.2.1/torchaudio-2.9.1%2Brocm7.2.1-cp312-cp312-win_amd64.whl

#ROCmホイールパッケージのインストール
python -m pip install --index-url https://repo.amd.com/rocm/whl/gfx110X-dgpu/ "rocm[libraries,devel]"

#HIPがsystemを認識できているかの確認
#自分のPC環境が表示されればOK
hipinfo

#ROCmとHIPがRX7800XTを認識できているか確認
#RX7800XT表示があればOK
python -c "import torch; print(torch.cuda.get_device_name(0) if torch.cuda.is_available() else 'None')"

#プログラムの書き換え
watermark.py
from __future__ import annotations

import logging
from collections.abc import Iterable

import torch

logger = logging.getLogger(__name__)

IRODORI_WATERMARK_PAYLOAD = (73, 82, 68, 84, 83) # "IRDTS"


def _as_single_channel_vector(audio: torch.Tensor) -> torch.Tensor | None:
squeezed = audio.detach().float().squeeze()
if squeezed.ndim == 0 or squeezed.numel() == 0:
return None
if squeezed.ndim == 1:
return squeezed
return squeezed.reshape(-1)


def _match_original_rank(audio: torch.Tensor, *, reference: torch.Tensor) -> torch.Tensor:
if reference.ndim == 2:
return audio.reshape(1, -1)
return audio.reshape(-1)


class SilentCipherWatermarker:
def __init__(self, *, device: str, model_type: str = "44.1k") -> None:
# MIOpenエラー回避のためウォーターマーク機能を無効化
self.model = None

@staticmethod
def _load_backend(*, device: str, model_type: str):
return None

@property
def ready(self) -> bool:
return False

def encode_one(
self,
audio: torch.Tensor,
*,
sample_rate: int,
payload: Iterable[int] = IRODORI_WATERMARK_PAYLOAD,
) -> torch.Tensor:
return audio

def encode_batch(self, audios: list[torch.Tensor], *, sample_rate: int) -> list[torch.Tensor]:
return audios

#プログラムの書き換え
gradio_app.py
#!/usr/bin/env python3
from __future__ import annotations

import argparse
from datetime import datetime
from pathlib import Path

import gradio as gr
from huggingface_hub import hf_hub_download

from irodori_tts.inference_runtime import (
RuntimeKey,
SamplingRequest,
clear_cached_runtime,
default_runtime_device,
get_cached_runtime,
list_available_runtime_devices,
list_available_runtime_precisions,
save_wav,
)
#生成秒数を30・0 から None へ変更
FIXED_SECONDS = None
MAX_GRADIO_CANDIDATES = 32
GRADIO_AUDIO_COLS_PER_ROW = 8


def _default_checkpoint() -> str:
candidates = sorted(
[
*Path(".").glob("**/checkpoint_*.pt"),
*Path(".").glob("**/checkpoint_*.safetensors"),
]
)
if not candidates:
return "Aratako/Irodori-TTS-500M-v2"
return str(candidates[-1])


def _default_model_device() -> str:
return default_runtime_device()


def _default_codec_device() -> str:
return default_runtime_device()


def _precision_choices_for_device(device: str) -> list[str]:
return list_available_runtime_precisions(device)


def _on_model_device_change(device: str) -> gr.Dropdown:
choices = _precision_choices_for_device(device)
return gr.Dropdown(choices=choices, value=choices[0])


def _on_codec_device_change(device: str) -> gr.Dropdown:
choices = _precision_choices_for_device(device)
return gr.Dropdown(choices=choices, value=choices[0])


def _parse_optional_float(raw: str | None, label: str) -> float | None:
if raw is None:
return None
text = str(raw).strip()
if text == "" or text.lower() == "none":
return None
try:
return float(text)
except ValueError as exc:
raise ValueError(f"{label} must be a float or blank.") from exc


def _parse_optional_int(raw: str | None, label: str) -> int | None:
if raw is None:
return None
text = str(raw).strip()
if text == "" or text.lower() == "none":
return None
try:
return int(text)
except ValueError as exc:
raise ValueError(f"{label} must be an int or blank.") from exc


def _format_timings(stage_timings: list[tuple[str, float]], total_to_decode: float) -> str:
lines = [
"[timing] ---- request ----",
*[f"[timing] {name}: {sec * 1000.0:.1f} ms" for name, sec in stage_timings],
f"[timing] total_to_decode: {total_to_decode:.3f} s",
]
return "\n".join(lines)


def _resolve_ref_wav(uploaded_audio: str | None) -> str | None:
if uploaded_audio is not None and str(uploaded_audio).strip() != "":
return str(uploaded_audio)
return None


def _resolve_checkpoint_path(raw_checkpoint: str) -> str:
checkpoint = str(raw_checkpoint).strip()
if checkpoint == "":
raise ValueError("checkpoint is required.")

suffix = Path(checkpoint).suffix.lower()
if suffix in {".pt", ".safetensors"}:
return checkpoint

resolved = hf_hub_download(repo_id=checkpoint, filename="model.safetensors")
print(f"[gradio] checkpoint: hf://{checkpoint} -> {resolved}", flush=True)
return str(resolved)


def _build_runtime_key(
checkpoint: str,
model_device: str,
model_precision: str,
codec_device: str,
codec_precision: str,
#enable_watermark: bool,
) -> RuntimeKey:
checkpoint_path = _resolve_checkpoint_path(checkpoint)
return RuntimeKey(
checkpoint=checkpoint_path,
model_device=str(model_device),
codec_repo="Aratako/Semantic-DACVAE-Japanese-32dim",
model_precision=str(model_precision),
codec_device=str(codec_device),
codec_precision=str(codec_precision),
#enable_watermark=bool(enable_watermark),
compile_model=False,
compile_dynamic=False,
)


def _load_model(
checkpoint: str,
model_device: str,
model_precision: str,
codec_device: str,
codec_precision: str,
enable_watermark: bool,
) -> str:
runtime_key = _build_runtime_key(
checkpoint=checkpoint,
model_device=model_device,
model_precision=model_precision,
codec_device=codec_device,
codec_precision=codec_precision,
#enable_watermark=enable_watermark,
)
_, reloaded = get_cached_runtime(runtime_key)
if reloaded:
status = "loaded model into memory"
else:
status = "model already loaded; reused existing runtime"
return (
f"{status}\n"
f"checkpoint: {runtime_key.checkpoint}\n"
f"model_device: {runtime_key.model_device}\n"
f"model_precision: {runtime_key.model_precision}\n"
f"codec_device: {runtime_key.codec_device}\n"
f"codec_precision: {runtime_key.codec_precision}"
)


def _run_generation(
checkpoint: str,
model_device: str,
model_precision: str,
codec_device: str,
codec_precision: str,
enable_watermark: bool,
text: str,
uploaded_audio: str | None,
num_steps: int,
num_candidates: int,
seed_raw: str,
cfg_guidance_mode: str,
cfg_scale_text: float,
cfg_scale_speaker: float,
cfg_scale_raw: str,
cfg_min_t: float,
cfg_max_t: float,
context_kv_cache: bool,
truncation_factor_raw: str,
rescale_k_raw: str,
rescale_sigma_raw: str,
speaker_kv_scale_raw: str,
speaker_kv_min_t_raw: str,
speaker_kv_max_layers_raw: str,
) -> tuple[object, ...]:
def stdout_log(msg: str) -> None:
print(msg, flush=True)

runtime_key = _build_runtime_key(
checkpoint=checkpoint,
model_device=model_device,
model_precision=model_precision,
codec_device=codec_device,
codec_precision=codec_precision,
#enable_watermark=enable_watermark,
)

if str(text).strip() == "":
raise ValueError("text is required.")
requested_candidates = int(num_candidates)
if requested_candidates <= 0:
raise ValueError("num_candidates must be >= 1.")
if requested_candidates > MAX_GRADIO_CANDIDATES:
raise ValueError(f"num_candidates must be <= {MAX_GRADIO_CANDIDATES}.")

cfg_scale = _parse_optional_float(cfg_scale_raw, "cfg_scale")
truncation_factor = _parse_optional_float(truncation_factor_raw, "truncation_factor")
rescale_k = _parse_optional_float(rescale_k_raw, "rescale_k")
rescale_sigma = _parse_optional_float(rescale_sigma_raw, "rescale_sigma")
speaker_kv_scale = _parse_optional_float(speaker_kv_scale_raw, "speaker_kv_scale")
speaker_kv_min_t = _parse_optional_float(speaker_kv_min_t_raw, "speaker_kv_min_t")
speaker_kv_max_layers = _parse_optional_int(speaker_kv_max_layers_raw, "speaker_kv_max_layers")
seed = _parse_optional_int(seed_raw, "seed")

ref_wav = _resolve_ref_wav(uploaded_audio=uploaded_audio)
no_ref = ref_wav is None
ref_normalize_db = -16.0
ref_ensure_max = True

runtime, reloaded = get_cached_runtime(runtime_key)
stdout_log(f"[gradio] runtime: {'reloaded' if reloaded else 'reused'}")
stdout_log(
(
"[gradio] request: model_device={} model_precision={} codec_device={} codec_precision={} "
"watermark={} mode={} seconds={} steps={} seed={} no_ref={} candidates={}"
).format(
model_device,
model_precision,
codec_device,
codec_precision,
enable_watermark,
cfg_guidance_mode,
FIXED_SECONDS,
num_steps,
"random" if seed is None else seed,
no_ref,
requested_candidates,
)
)

result = runtime.synthesize(
SamplingRequest(
text=str(text),
ref_wav=ref_wav,
ref_latent=None,
no_ref=bool(no_ref),
ref_normalize_db=ref_normalize_db,
ref_ensure_max=bool(ref_ensure_max),
num_candidates=requested_candidates,
decode_mode="sequential",
seconds=FIXED_SECONDS,
max_ref_seconds=30.0,
max_text_len=None,
num_steps=int(num_steps),
seed=None if seed is None else int(seed),
cfg_guidance_mode=str(cfg_guidance_mode),
cfg_scale_text=float(cfg_scale_text),
cfg_scale_speaker=float(cfg_scale_speaker),
cfg_scale=cfg_scale,
cfg_min_t=float(cfg_min_t),
cfg_max_t=float(cfg_max_t),
truncation_factor=truncation_factor,
rescale_k=rescale_k,
rescale_sigma=rescale_sigma,
context_kv_cache=bool(context_kv_cache),
speaker_kv_scale=speaker_kv_scale,
speaker_kv_min_t=speaker_kv_min_t,
speaker_kv_max_layers=speaker_kv_max_layers,
trim_tail=True,
),
log_fn=stdout_log,
)

out_dir = Path("gradio_outputs")
out_dir.mkdir(parents=True, exist_ok=True)
stamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
out_paths: list[str] = []
for i, audio in enumerate(result.audios, start=1):
out_path = save_wav(
out_dir / f"sample_{stamp}_{i:03d}.wav",
audio.float(),
result.sample_rate,
)
out_paths.append(str(out_path))

runtime_msg = "runtime: reloaded" if reloaded else "runtime: reused"
detail_lines = [
runtime_msg,
f"seed_used: {result.used_seed}",
f"candidates: {len(result.audios)}",
*[f"saved[{i}]: {path}" for i, path in enumerate(out_paths, start=1)],
*result.messages,
]
detail_text = "\n".join(detail_lines)
timing_text = _format_timings(result.stage_timings, result.total_to_decode)
stdout_log(f"[gradio] saved {len(out_paths)} candidates")

audio_updates: list[object] = []
for i in range(MAX_GRADIO_CANDIDATES):
if i < len(out_paths):
audio_updates.append(gr.update(value=out_paths[i], visible=True))
else:
audio_updates.append(gr.update(value=None, visible=False))
return (*audio_updates, detail_text, timing_text)


def _clear_runtime_cache() -> str:
clear_cached_runtime()
return "cleared loaded model from memory"


def build_ui() -> gr.Blocks:
default_checkpoint = _default_checkpoint()
default_model_device = _default_model_device()
default_codec_device = _default_codec_device()
# 修正後
device_choices = ["cuda", "cpu"]
model_precision_choices = _precision_choices_for_device(default_model_device)
codec_precision_choices = _precision_choices_for_device(default_codec_device)

with gr.Blocks(title="Irodori-TTS Gradio") as demo:
gr.Markdown("# Irodori-TTS Inference (Cached Runtime)")
gr.Markdown(
"When settings are unchanged, runtime is reused and only sampling/decoding runs."
)

with gr.Row():
checkpoint = gr.Textbox(
label="Checkpoint (.pt/.safetensors or HF repo id)",
value=default_checkpoint,
scale=4,
)
# model_device = gr.Dropdown(
# label="Model Device",
# choices=device_choices,
# value=default_model_device,
# scale=1,
# )

model_device = gr.Dropdown(
label="Model Device",
choices=device_choices,
value="cuda", # 強制的にcudaを選択状態にする
scale=1,
)

model_precision = gr.Dropdown(
label="Model Precision",
choices=model_precision_choices,
value=model_precision_choices[0],
scale=1,
)
codec_device = gr.Dropdown(
label="Codec Device",
choices=device_choices,
value=default_codec_device,
scale=1,
)
codec_precision = gr.Dropdown(
label="Codec Precision",
choices=codec_precision_choices,
value=codec_precision_choices[0],
scale=1,
)
enable_watermark = gr.State(False)

with gr.Row():
load_model_btn = gr.Button("Load Model")
clear_cache_btn = gr.Button("Unload Model")
clear_cache_msg = gr.Textbox(label="Model Status", interactive=False)

text = gr.Textbox(label="Text", lines=4)
uploaded_audio = gr.Audio(
label="Reference Audio Upload (optional, blank = no-reference mode)",
type="filepath",
)

with gr.Accordion("Sampling", open=True):
with gr.Row():
num_steps = gr.Slider(label="Num Steps", minimum=1, maximum=120, value=40, step=1)
num_candidates = gr.Slider(
label="Num Candidates",
minimum=1,
maximum=MAX_GRADIO_CANDIDATES,
value=1,
step=1,
)
seed_raw = gr.Textbox(label="Seed (blank=random)", value="")

with gr.Row():
cfg_guidance_mode = gr.Dropdown(
label="CFG Guidance Mode",
choices=["independent", "joint", "alternating"],
value="independent",
)
cfg_scale_text = gr.Slider(
label="CFG Scale Text",
minimum=0.0,
maximum=10.0,
value=3.0,
step=0.1,
)
cfg_scale_speaker = gr.Slider(
label="CFG Scale Speaker",
minimum=0.0,
maximum=10.0,
value=5.0,
step=0.1,
)

with gr.Accordion("Advanced (Optional)", open=False):
cfg_scale_raw = gr.Textbox(label="CFG Scale Override (optional)", value="")
with gr.Row():
cfg_min_t = gr.Number(label="CFG Min t", value=0.5)
cfg_max_t = gr.Number(label="CFG Max t", value=1.0)
context_kv_cache = gr.Checkbox(label="Context KV Cache", value=True)
with gr.Row():
truncation_factor_raw = gr.Textbox(label="Truncation Factor (optional)", value="")
rescale_k_raw = gr.Textbox(label="Rescale k (optional)", value="")
rescale_sigma_raw = gr.Textbox(label="Rescale sigma (optional)", value="")
with gr.Row():
speaker_kv_scale_raw = gr.Textbox(label="Speaker KV Scale (optional)", value="")
speaker_kv_min_t_raw = gr.Textbox(label="Speaker KV Min t (optional)", value="0.9")
speaker_kv_max_layers_raw = gr.Textbox(
label="Speaker KV Max Layers (optional)", value=""
)

generate_btn = gr.Button("Generate", variant="primary")

out_audios: list[gr.Audio] = []
num_rows = (
MAX_GRADIO_CANDIDATES + GRADIO_AUDIO_COLS_PER_ROW - 1
) // GRADIO_AUDIO_COLS_PER_ROW
with gr.Column():
for row_idx in range(num_rows):
with gr.Row():
for col_idx in range(GRADIO_AUDIO_COLS_PER_ROW):
i = row_idx * GRADIO_AUDIO_COLS_PER_ROW + col_idx
if i >= MAX_GRADIO_CANDIDATES:
break
out_audios.append(
gr.Audio(
label=f"Generated Audio {i + 1}",
type="filepath",
interactive=False,
visible=(i == 0),
min_width=160,
)
)
out_log = gr.Textbox(label="Run Log", lines=8)
out_timing = gr.Textbox(label="Timing", lines=8)

generate_btn.click(
_run_generation,
inputs=[
checkpoint,
model_device,
model_precision,
codec_device,
codec_precision,
enable_watermark,
text,
uploaded_audio,
num_steps,
num_candidates,
seed_raw,
cfg_guidance_mode,
cfg_scale_text,
cfg_scale_speaker,
cfg_scale_raw,
cfg_min_t,
cfg_max_t,
context_kv_cache,
truncation_factor_raw,
rescale_k_raw,
rescale_sigma_raw,
speaker_kv_scale_raw,
speaker_kv_min_t_raw,
speaker_kv_max_layers_raw,
],
outputs=[*out_audios, out_log, out_timing],
)
model_device.change(
_on_model_device_change, inputs=[model_device], outputs=[model_precision]
)
codec_device.change(
_on_codec_device_change, inputs=[codec_device], outputs=[codec_precision]
)

load_model_btn.click(
_load_model,
inputs=[
checkpoint,
model_device,
model_precision,
codec_device,
codec_precision,
enable_watermark,
],
outputs=[clear_cache_msg],
)
clear_cache_btn.click(_clear_runtime_cache, outputs=[clear_cache_msg])

return demo


def main() -> None:
parser = argparse.ArgumentParser(description="Gradio app for Irodori-TTS with cached runtime.")
parser.add_argument("--server-name", default="127.0.0.1")
parser.add_argument("--server-port", type=int, default=7860)
parser.add_argument("--share", action="store_true")
parser.add_argument("--debug", action="store_true")
args = parser.parse_args()

demo = build_ui()
demo.queue(default_concurrency_limit=1)
demo.launch(
server_name=args.server_name,
server_port=args.server_port,
share=bool(args.share),
debug=bool(args.debug),
)


if __name__ == "__main__":
main()


文字数制限でこれ以上書き込めないので、続きます。
Posted at 2026/07/22 20:49:55 | コメント(0) | トラックバック(0) | PC | パソコン/インターネット
2026年05月22日 イイね!

Radeonでirodori-ttsを動かした方法。(後で忘れないように記録)

インストールしておくものGeForce用の一式+Rocm6.3今のところ7系だとうまいこと動いてくれない。
Python 3.11.9で実行

Irodoti-tts\BAT\通常起動.bat

@echo off
chcp 65001 > nul
set "BAT_DIR=%~dp0"

:: 【重要】BATフォルダから1つ上の親フォルダ(Irodori-TTS)にカレントディレクトリを移動
cd /d "%BAT_DIR%"
cd ..
set "ROOT_DIR=%cd%"

echo ===================================================
echo [1/3] AMD GPU (ROCm/HIP) 向け
echo ===================================================
::環境変数を注入
set AMD_SERIALIZE_KERNEL=0
set TORCH_USE_HIP_DSA=1

:: コンパイラとGPUアーキテクチャの定義(RX7800XT用)
set "CC=clang-cl"
set "CXX=clang-cl"
set DISTUTILS_USE_SDK=1
set HSA_OVERRIDE_GFX_VERSION=11.0.0

:: MIOpen / Triton / HFのキャッシュパスを親フォルダ基準に修正
set MIOPEN_FIND_MODE=FAST
set MIOPEN_LOG_LEVEL=3
set "MIOPEN_USER_DB_PATH=%ROOT_DIR%\.miopen_db"
set "TRITON_CACHE_DIR=%ROOT_DIR%\.triton_cache"
set "HF_HOME=%ROOT_DIR%\.cache\huggingface"

:: ROCm SDKのパス解決
set "ROCMSDKCORE_PATH=%ROOT_DIR%\.venv\Lib\site-packages\_rocm_sdk_core"
set PATH=%ROCMSDKCORE_PATH%\lib\llvm\bin;%ROCMSDKCORE_PATH%\bin;%PATH%

echo.
echo ===================================================
echo [2/3] 仮想環境のPythonを確認
echo ===================================================
if exist ".venv\Scripts\activate.bat" (
echo 仮想環境 .venv を有効化します。
call .venv\Scripts\activate.bat
) else (
echo [エラー] .venv が見つかりません。現在のディレクトリ: %cd%
pause
exit /b
)

echo.
echo ===================================================
echo [3/3] 音声合成(Gradio WebUI)を起動します...
echo ===================================================
echo 実行ルートディレクトリ: %cd%

:: WebUIの起動
python rocm_launcher_gradio_app.py --server-name 0.0.0.0 --server-port 7860

if %errorlevel% neq 0 (
echo.
echo [エラー] アプリケーションが異常終了しました。
)

pause

ここまで
何回かechoさせているのは、動いてるのか止まっているのか確認用

次は、学習用の設定(ディレクトリは決め打ちバージョン)
Irodori-tts\BAT¥学習準備用.bat


@echo off
setlocal enabledelayedexpansion

REM --- バッチがある「BAT」フォルダから、プロジェクトのルート「Irodori-TTS」に移動 ---
cd /d "%~dp0.."

REM --- ログを強制的に残すための設定(パスを修正) ---
if not "%1"=="STAY" (start cmd /k "%~f0" STAY & exit)

REM --- Environment Setup ---
set "ROCM_PATH=C:\Program Files\AMD\ROCm\6.4\bin"
set "ROCMSDKCORE_PATH=%CD%\.venv\Lib\site-packages\_rocm_sdk_core"
set "TORCHCODEC_DIR=%CD%\.venv\Lib\site-packages\torchcodec"

REM Windowsのシステムパスを崩さないよう、後ろに追加
set "PATH=%PATH%;%ROCM_PATH%;%TORCHCODEC_DIR%;%ROCMSDKCORE_PATH%\bin;%ROCMSDKCORE_PATH%\lib"

REM --- Compilation / Runtime Flags ---
set "HIP_PATH=%ROCM_PATH%"
set "CC=clang-cl"
set "CXX=clang-cl"
set "DISTUTILS_USE_SDK=1"
set "HSA_OVERRIDE_GFX_VERSION=11.0.0"
set "HF_HOME=%CD%\.cache\huggingface"
set "ARROW_DEFAULT_MEMORY_POOL=system"

REM --- Path Settings ---
set "DATASET_DIR=<b>「インストールしたドライブ+ディレクトリ」</b>\Irodori-TTS\my_dataset\「学習ファイル用フォルダ名」"
set "OUTPUT_NAME=<b>「インストールしたドライブ+ディレクトリ」</b>\Irodori-TTS\my_dataset\「学習ファイル用フォルダ名」\manifest.jsonl"
set "LATENT_DIR=<b>「インストールしたドライブ+ディレクトリ」</b>\Irodori-TTS\my_dataset\「学習ファイル用フォルダ名」\latents"

echo [STEP 1] Starting Manifest Preparation...
echo [INFO] Dataset Directory: %DATASET_DIR%

REM --- Execution (カレントディレクトリ基準で実行) ---
".venv\Scripts\python.exe" "rocm_launcher_prepare_manifest.py" --dataset "%DATASET_DIR%" --audio-column "audio" --text-column "text" --output-manifest "%OUTPUT_NAME%" --latent-dir "%LATENT_DIR%"

REM ERRORLEVELの判定
if %ERRORLEVEL% NEQ 0 goto :FAILURE

:SUCCESS
echo.
echo ===================================================
echo [SUCCESS] Process Completed!
echo Output: %OUTPUT_NAME%
echo ===================================================
goto :END

:FAILURE
echo.
echo ===================================================
echo [ERROR] Process Failed.
echo Error Level: %ERRORLEVEL%
echo ===================================================

:END
pause

ここまで
my_dataset\「フォルダ名」を作って、waveファイルと読み方をCSVにしておく。
metadata.csv
./「ファイル名1」.wav,「読み方1」
./「ファイル名2」.wav,「読み方2」

ノイズのないwavファイルをたくさん用意する。



次は、学習用

学習開始.bat

@echo off
set TORCH_ROCM_AOTRITON_ENABLE_EXPERIMENTAL=1
:: 【追加】デッドロックやカーネルフリーズを防ぐ安全設定
set TORCH_SDP_KERNEL_FORCE_MATH=1
set TORCH_BLAS_PREFER_HIPBLASLT=0

chcp 65001 > nul
set CURRENT_DIR=%~dp0

cd /d "%CURRENT_DIR%"
if exist "..\train.py" (
cd ..
)

echo ===================================================
echo [0/3] Training Parameter Settings (Press Enter for Default)
echo ===================================================

set "INPUT_STEPS=15000"
set /p "INPUT_STEPS=- Total Steps (Default: %INPUT_STEPS%): "

set "INPUT_SAVE_EVERY=1000"
set /p "INPUT_SAVE_EVERY=- Save Every steps (Default: %INPUT_SAVE_EVERY%): "

set "INPUT_WARMUP=500"
set /p "INPUT_WARMUP=- Warmup Steps (Default: %INPUT_WARMUP%): "

echo.
echo ---------------------------------------------------
echo 0だと非同期で速い、1だと同期で待ち時間が多く遅いけど確実に動く
echo ---------------------------------------------------
set "INPUT_SERIALIZE=0"
set /p "INPUT_SERIALIZE=- AMD_SERIALIZE_KERNEL (0=Normal, 1=Debug): "

set "INPUT_DSA=0"
set /p "INPUT_DSA=- TORCH_USE_HIP_DSA (0=Disable, 1=Enable Debug): "
echo.

echo ---------------------------------------------------
echo Settings completed.
echo Press any key to apply variables and start training.
echo ---------------------------------------------------
pause
echo.

echo ===================================================
echo [1/3] Setting up AMD GPU
echo ===================================================
set "AMD_SERIALIZE_KERNEL=%INPUT_SERIALIZE%"
set "TORCH_USE_HIP_DSA=%INPUT_DSA%"

echo Applied Environment Variables:
echo AMD_SERIALIZE_KERNEL = %AMD_SERIALIZE_KERNEL%
echo TORCH_USE_HIP_DSA = %TORCH_USE_HIP_DSA%

echo.
echo ===================================================
echo [2/3] 仮想環境のチェック「.venv」で実行の場合
echo ===================================================
if exist ".venv\Scripts\activate.bat" (
echo Activating .venv ...
call .venv\Scripts\activate.bat
) else (
echo [WARNING] .venv not found. Using system Python.
)

echo.
echo ===================================================
echo [3/3] 環境表示
echo ===================================================
echo Working Directory: %cd%
echo Parameters:
echo Total Steps: %INPUT_STEPS%
echo Save Every : %INPUT_SAVE_EVERY%
echo Warmup : %INPUT_WARMUP%
echo.

:: 末尾に --num-workers 0 を追加し動作停止対策
python train.py --config configs/train_500m_v2_lora.yaml --manifest "<b>「インストールしたドライブ+ディレクトリ」</b>\Irodori-TTS\my_dataset\「学習ファイル用フォルダ名」\manifest.jsonl" --init-checkpoint "D:\Utilities\AI\Irodori-TTS\model.safetensors" --batch-size 4 --gradient-accumulation-steps 1 --max-steps %INPUT_STEPS% --save-every %INPUT_SAVE_EVERY% --warmup-steps %INPUT_WARMUP% --num-workers 0

if %errorlevel% neq 0 (
echo.
echo [ERROR] Training failed. Please check the logs above.
)

pause

学習前の基本用modelを「model.safetensors」として、Irodori-ttsフォルダに入れておく。
学習後のものを追加学習するときは、変更する。

RocmやPythonのバージョンが変わると動かなかったので、何とか動かせるバージョン
学習回数やほかのパラメータは、忘れても検索したら何とかなる。
20,000stepくらいは回した方が良いので、寝てる間にやらせよう
回数以上に重要なのは、きれいなノイズのない音声ファイル
たくさんの声を覚えさせた方が、オリジナルに近くなる。
Posted at 2026/05/22 18:52:57 | コメント(0) | 備忘録 | パソコン/インターネット
2023年11月12日 イイね!

何かやってる?

何かやってる?BMWミーティング
Posted at 2023/11/12 09:28:24 | コメント(0) | トラックバック(0)
2022年11月18日 イイね!

ぶつけられた・・・

東北自動車道 上り線 323.2kp
登坂車線合流点で、停車中です。
トラックの人達ごめんなさい、
Posted at 2022/11/18 08:59:16 | コメント(0) | トラックバック(0)

プロフィール

「@タッキーR よし、わかった!フェンダーを切って、盛ったら陸運局に走る流れだな!」
何シテル?   11/29 12:57
狄雲です。 きどすけから、H/N指定でアカウントを取れって命令が・・・ 面倒なので、狄雲に戻しました!! 何となくH/N変更中@以降が変わります ス...
みんカラ新規会員登録

ユーザー内検索

<< 2026/8 >>

      1
2345678
9101112131415
16171819202122
23242526272829
3031     

リンク・クリップ

クラッチ・レリーズシリンダー位置調整ほか。 
カテゴリ:その他(カテゴリ未設定)
2022/02/15 16:20:01
通販業者VS-ONEの対応に怒ってもイイよね! 
カテゴリ:その他(カテゴリ未設定)
2021/11/29 08:27:26
TRD TRDネックパッド 
カテゴリ:その他(カテゴリ未設定)
2021/09/20 13:28:27

愛車一覧

スバル BRZ スバル BRZ
2020年 7月19日発注 2020年10月10日納車 総支払額275万で提示されたので ...
ホンダ トルネオ ホンダ トルネオ
走行距離11,000kmのを中古で19年くらい やっと60,200km走りました。 追 ...
日産 キャラバン 日産 キャラバン
五月の車検前に廃車予定
その他 その他 その他 その他
コンパクトFR 扱いやすく、そのままサーキットにも出られる優れもの 車体重量は、たぶん ...

過去のブログ

2026年
01月02月03月04月05月06月
07月08月09月10月11月12月
2023年
01月02月03月04月05月06月
07月08月09月10月11月12月
2022年
01月02月03月04月05月06月
07月08月09月10月11月12月
2021年
01月02月03月04月05月06月
07月08月09月10月11月12月
2020年
01月02月03月04月05月06月
07月08月09月10月11月12月
2014年
01月02月03月04月05月06月
07月08月09月10月11月12月
2013年
01月02月03月04月05月06月
07月08月09月10月11月12月
2012年
01月02月03月04月05月06月
07月08月09月10月11月12月
2011年
01月02月03月04月05月06月
07月08月09月10月11月12月
2010年
01月02月03月04月05月06月
07月08月09月10月11月12月
2009年
01月02月03月04月05月06月
07月08月09月10月11月12月
2008年
01月02月03月04月05月06月
07月08月09月10月11月12月
ヘルプ利用規約サイトマップ
© LY Corporation