harp-dev commited on
Commit
babe9bf
·
verified ·
1 Parent(s): b37d230

Resample an edit that runs on, up to three times, and explain the edit interval

Browse files
Files changed (1) hide show
  1. app.py +41 -17
app.py CHANGED
@@ -94,6 +94,14 @@ def process_fn(audio_path: str, target_text: str, start_time: float, end_time: f
94
  return regenerate(audio_path, target_text, start_time, end_time, duration)
95
 
96
 
 
 
 
 
 
 
 
 
97
  @spaces.GPU(duration=60)
98
  def regenerate(audio_path: str, target_text: str, start_time: float, end_time: float,
99
  duration: float) -> str:
@@ -109,22 +117,35 @@ def regenerate(audio_path: str, target_text: str, start_time: float, end_time: f
109
  "codec_sr": CODEC_RATE,
110
  "silence_tokens": [1388, 1898, 131],
111
  }
112
- generated = inference_one_sample(
113
- model,
114
- model.args,
115
- model.args.phn2num,
116
- text_tokenizer,
117
- audio_tokenizer,
118
- audio_path,
119
- target_text,
120
- mask,
121
- DEVICE,
122
- decode_config,
123
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
124
  # The model is mono at 16 kHz, so the result is resampled back to the input's rate and copied
125
  # across its channels
126
  input_info = sf.info(audio_path)
127
- audio = generated[0].detach().cpu().float()
128
  if input_info.samplerate != 16000:
129
  audio = torchaudio.functional.resample(audio, 16000, input_info.samplerate)
130
  audio = audio[:1].T.repeat(1, input_info.channels)
@@ -145,12 +166,15 @@ if __name__ == "__main__":
145
  .set_info("English speech to edit, up to 60 seconds."),
146
  gr.Textbox(label="Target Transcript", lines=4)
147
  .harp_required(True)
148
- .set_info("Full transcript of the recording, with the replacement words in place, "
149
- "up to 500 characters."),
 
150
  gr.Number(label="Edit Start (seconds)", value=0.5, precision=2)
151
- .set_info("Start of the words to replace."),
 
152
  gr.Number(label="Edit End (seconds)", value=1.5, precision=2)
153
- .set_info("End of the words to replace."),
 
154
  ],
155
  output_components=[
156
  gr.Audio(type="filepath", label="Edited Speech")
 
94
  return regenerate(audio_path, target_text, start_time, end_time, duration)
95
 
96
 
97
+ # The replacement is generated token by token until the model decides it has ended, and it
98
+ # sometimes runs on, stretching a two-second edit into ten seconds of speech. A result is
99
+ # accepted when the recording has grown by no more than this many seconds, and otherwise the
100
+ # edit is sampled again, up to the limit below, keeping the shortest result.
101
+ MAX_GROWTH_SECONDS = 2.0
102
+ MAX_ATTEMPTS = 3
103
+
104
+
105
  @spaces.GPU(duration=60)
106
  def regenerate(audio_path: str, target_text: str, start_time: float, end_time: float,
107
  duration: float) -> str:
 
117
  "codec_sr": CODEC_RATE,
118
  "silence_tokens": [1388, 1898, 131],
119
  }
120
+ best = None
121
+ for attempt in range(MAX_ATTEMPTS):
122
+ generated = inference_one_sample(
123
+ model,
124
+ model.args,
125
+ model.args.phn2num,
126
+ text_tokenizer,
127
+ audio_tokenizer,
128
+ audio_path,
129
+ target_text,
130
+ mask,
131
+ DEVICE,
132
+ decode_config,
133
+ )
134
+ candidate = generated[0].detach().cpu().float()
135
+ seconds = candidate.shape[-1] / 16000
136
+ print(f"VoiceCraft: attempt {attempt + 1} gives {seconds:.1f} s for a {duration:.1f} s "
137
+ "recording", flush=True)
138
+ if best is None or candidate.shape[-1] < best.shape[-1]:
139
+ best = candidate
140
+ if seconds <= duration + MAX_GROWTH_SECONDS:
141
+ break
142
+ # A sample that ran on is more likely to stop with silence penalized harder
143
+ decode_config["stop_repetition"] = max(1, decode_config["stop_repetition"] - 1)
144
+
145
  # The model is mono at 16 kHz, so the result is resampled back to the input's rate and copied
146
  # across its channels
147
  input_info = sf.info(audio_path)
148
+ audio = best
149
  if input_info.samplerate != 16000:
150
  audio = torchaudio.functional.resample(audio, 16000, input_info.samplerate)
151
  audio = audio[:1].T.repeat(1, input_info.channels)
 
166
  .set_info("English speech to edit, up to 60 seconds."),
167
  gr.Textbox(label="Target Transcript", lines=4)
168
  .harp_required(True)
169
+ .set_info("The whole transcript of the recording, as it should read after the "
170
+ "edit, up to 500 characters. Only the words inside the edit interval "
171
+ "are regenerated, so change those and leave the rest as spoken."),
172
  gr.Number(label="Edit Start (seconds)", value=0.5, precision=2)
173
+ .set_info("Where the words to replace begin, in seconds from the start of the "
174
+ "recording. Read the time off the ruler of the input track."),
175
  gr.Number(label="Edit End (seconds)", value=1.5, precision=2)
176
+ .set_info("Where the words to replace end, in seconds. The interval should cover "
177
+ "whole words, and a little silence on either side helps."),
178
  ],
179
  output_components=[
180
  gr.Audio(type="filepath", label="Edited Speech")