build_dataset.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. import re
  2. from collections import defaultdict
  3. from multiprocessing import Pool
  4. import numpy as np
  5. from loguru import logger
  6. from tqdm import tqdm
  7. from fish_speech.datasets.protos.text_data_pb2 import Semantics, Sentence, TextData
  8. from fish_speech.datasets.protos.text_data_stream import pack_pb_stream
  9. from fish_speech.text import g2p
  10. from fish_speech.utils.file import AUDIO_EXTENSIONS, list_files
  11. # Define datasets
  12. DATASETS = [
  13. # (root, name, languages, extension, group parent level)
  14. ("data/StarRail/Chinese", "StarRail", ["ZH", "EN"], ".lab", 1),
  15. ("data/StarRail/English", "StarRail", ["EN"], ".lab", 1),
  16. ("data/StarRail/Japanese", "StarRail", ["JP", "EN"], ".lab", 1),
  17. ("data/Genshin/Chinese", "Genshin", ["ZH", "EN"], ".lab", 1),
  18. ("data/Genshin/English", "Genshin", ["EN"], ".lab", 1),
  19. ("data/Genshin/Japanese", "Genshin", ["JP", "EN"], ".lab", 1),
  20. ("data/LibriTTS_R", "LibriTTS_R", ["EN"], ".normalized.txt", 2),
  21. ("data/WenetSpeech", "WenetSpeech", ["ZH", "EN"], ".txt", 1),
  22. ]
  23. def task_generator():
  24. for root, source, languages, extension, parent_level in DATASETS:
  25. # Load the files
  26. files = list_files(root, AUDIO_EXTENSIONS, recursive=True)
  27. grouped_files = defaultdict(list)
  28. for file in files:
  29. if parent_level == 1:
  30. p = file.parent.name
  31. elif parent_level == 2:
  32. p = file.parent.parent.name
  33. else:
  34. raise ValueError(f"Invalid parent level {parent_level}")
  35. grouped_files[p].append(file)
  36. logger.info(f"Found {len(grouped_files)} groups in {root}")
  37. for name, subset in grouped_files.items():
  38. yield name, subset, source, languages, extension
  39. def run_task(task):
  40. name, subset, source, languages, extension = task
  41. # Parse the files
  42. sentences = []
  43. for file in subset:
  44. np_file = file.with_suffix(".npy")
  45. txt_file = file.with_suffix(extension)
  46. if np_file.exists() is False or txt_file.exists() is False:
  47. continue
  48. with open(txt_file, "r") as f:
  49. text = f.read().strip()
  50. # Simple cleaning: replace { xxx } and < xxx > with space
  51. text = re.sub(r"\{.*?\}", " ", text)
  52. text = re.sub(r"<.*?>", " ", text)
  53. text = re.sub(r"\s+", " ", text)
  54. try:
  55. phones = [v for _, v in g2p(text, order=languages)]
  56. semantics = np.load(np_file)
  57. except Exception as e:
  58. logger.error(f"Failed to parse {file}: {e}")
  59. continue
  60. if isinstance(semantics, np.ndarray):
  61. semantics = semantics.tolist()
  62. sentences.append(
  63. Sentence(
  64. text=text,
  65. phones=phones,
  66. semantics=[Semantics(values=s) for s in semantics],
  67. )
  68. )
  69. # Pack the sentences
  70. return pack_pb_stream(
  71. TextData(
  72. source=source,
  73. name=name,
  74. languages=languages,
  75. sentences=sentences,
  76. )
  77. )
  78. def main():
  79. dataset_fp = open("data/quantized-dataset-1208.protos", "wb")
  80. with Pool(16) as p:
  81. for result in tqdm(p.imap_unordered(run_task, task_generator())):
  82. dataset_fp.write(result)
  83. dataset_fp.close()
  84. if __name__ == "__main__":
  85. main()