prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Unable to use svc pre-sd with pyannote.audio 3.1.1
  ### Describe the bug
  
  To use svc pre-sd for a long audio file with multiple speakers, I followed the [setup guide](https://github.com/voicepaw/so-vits-svc-fork/#before-training) and manually installed pyannote.audio, getting the latest version, 3.1.1.
  
  Attempting to run svc pre-sd triggered the following error messages:
  
  ```
  Model was trained with pyannote.audio 0.0.1, yours is 3.1.1. Bad things might happen unless you revert pyannote.audio to 0.x.
  
  Model was trained with torch 1.10.0+cu102, yours is 2.2.2+cu121. Bad things might happen unless you revert torch to 1.x.
  ```
  
  According to [PyPI](https://pypi.org/project/pyannote.audio/3.1.1/), pyannote.audio 3.1.1 works with speaker-diarization-3.1. So, it’s necessary to explicitly specify this version in the code.
  
  ### To Reproduce
  
  1. Set up the environment. (I'm using torch 2.2.2+cu121.)
  2. Install so-vits-svc-fork and its dependencies.
  3. Install pyannote.audio with `pip3 install pyannote-audio`.
  4. Prepare your data and organize data folders.
  5. Run svc pre-sd with options suited to your data.
  
  ### Additional context
  
  _No response_
  
  ### Version
  
  4.1.61
  
  ### Platform
  
  WSL-Ubuntu 22.04 LTS
  
  ### Code of Conduct
  
  - [X] I agree to follow this project's Code of Conduct.
  
  ### No Duplicate
  
  - [X] I have checked existing issues to avoid duplicates.
  
  </issue>
  <code>
  [start of src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py]
  1 from __future__ import annotations
  2 
  3 from collections import defaultdict
  4 from logging import getLogger
  5 from pathlib import Path
  6 
  7 import librosa
  8 import soundfile as sf
  9 import torch
  10 from joblib import Parallel, delayed
  11 from pyannote.audio import Pipeline
  12 from tqdm import tqdm
  13 from tqdm_joblib import tqdm_joblib
  14 
  15 LOG = getLogger(__name__)
  16 
  17 
  18 def _process_one(
  19     input_path: Path,
  20     output_dir: Path,
  21     sr: int,
  22     *,
  23     min_speakers: int = 1,
  24     max_speakers: int = 1,
  25     huggingface_token: str | None = None,
  26 ) -> None:
  27     try:
  28         audio, sr = librosa.load(input_path, sr=sr, mono=True)
  29     except Exception as e:
  30         LOG.warning(f"Failed to read {input_path}: {e}")
  31         return
  32     pipeline = Pipeline.from_pretrained(
  33         "pyannote/speaker-diarization", use_auth_token=huggingface_token
  34     )
  35     if pipeline is None:
  36         raise ValueError("Failed to load pipeline")
  37     pipeline = pipeline.to(torch.device("cuda"))
  38     LOG.info(f"Processing {input_path}. This may take a while...")
  39     diarization = pipeline(
  40         input_path, min_speakers=min_speakers, max_speakers=max_speakers
  41     )
  42 
  43     LOG.info(f"Found {len(diarization)} tracks, writing to {output_dir}")
  44     speaker_count = defaultdict(int)
  45 
  46     output_dir.mkdir(parents=True, exist_ok=True)
  47     for segment, track, speaker in tqdm(
  48         list(diarization.itertracks(yield_label=True)), desc=f"Writing {input_path}"
  49     ):
  50         if segment.end - segment.start < 1:
  51             continue
  52         speaker_count[speaker] += 1
  53         audio_cut = audio[int(segment.start * sr) : int(segment.end * sr)]
  54         sf.write(
  55             (output_dir / f"{speaker}_{speaker_count[speaker]}.wav"),
  56             audio_cut,
  57             sr,
  58         )
  59 
  60     LOG.info(f"Speaker count: {speaker_count}")
  61 
  62 
  63 def preprocess_speaker_diarization(
  64     input_dir: Path | str,
  65     output_dir: Path | str,
  66     sr: int,
  67     *,
  68     min_speakers: int = 1,
  69     max_speakers: int = 1,
  70     huggingface_token: str | None = None,
  71     n_jobs: int = -1,
  72 ) -> None:
  73     if huggingface_token is not None and not huggingface_token.startswith("hf_"):
  74         LOG.warning("Huggingface token probably should start with hf_")
  75     if not torch.cuda.is_available():
  76         LOG.warning("CUDA is not available. This will be extremely slow.")
  77     input_dir = Path(input_dir)
  78     output_dir = Path(output_dir)
  79     input_dir.mkdir(parents=True, exist_ok=True)
  80     output_dir.mkdir(parents=True, exist_ok=True)
  81     input_paths = list(input_dir.rglob("*.*"))
  82     with tqdm_joblib(desc="Preprocessing speaker diarization", total=len(input_paths)):
  83         Parallel(n_jobs=n_jobs)(
  84             delayed(_process_one)(
  85                 input_path,
  86                 output_dir / input_path.relative_to(input_dir).parent / input_path.stem,
  87                 sr,
  88                 max_speakers=max_speakers,
  89                 min_speakers=min_speakers,
  90                 huggingface_token=huggingface_token,
  91             )
  92             for input_path in input_paths
  93         )
  94
  [end of src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py b/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py
  --- a/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py
  +++ b/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py
  @@ -30,7 +30,7 @@
           LOG.warning(f"Failed to read {input_path}: {e}")
           return
       pipeline = Pipeline.from_pretrained(
  -        "pyannote/speaker-diarization", use_auth_token=huggingface_token
  +        "pyannote/speaker-diarization-3.1", use_auth_token=huggingface_token
       )
       if pipeline is None:
           raise ValueError("Failed to load pipeline")
  
verification_info: {"golden_diff": "diff --git a/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py b/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py\n--- a/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py\n+++ b/src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py\n@@ -30,7 +30,7 @@\n         LOG.warning(f\"Failed to read {input_path}: {e}\")\n         return\n     pipeline = Pipeline.from_pretrained(\n-        \"pyannote/speaker-diarization\", use_auth_token=huggingface_token\n+        \"pyannote/speaker-diarization-3.1\", use_auth_token=huggingface_token\n     )\n     if pipeline is None:\n         raise ValueError(\"Failed to load pipeline\")\n", "issue": "Unable to use svc pre-sd with pyannote.audio 3.1.1\n### Describe the bug\n\nTo use svc pre-sd for a long audio file with multiple speakers, I followed the [setup guide](https://github.com/voicepaw/so-vits-svc-fork/#before-training) and manually installed pyannote.audio, getting the latest version, 3.1.1.\r\n\r\nAttempting to run svc pre-sd triggered the following error messages:\r\n\r\n```\r\nModel was trained with pyannote.audio 0.0.1, yours is 3.1.1. Bad things might happen unless you revert pyannote.audio to 0.x.\r\n\r\nModel was trained with torch 1.10.0+cu102, yours is 2.2.2+cu121. Bad things might happen unless you revert torch to 1.x.\r\n```\r\n\r\nAccording to [PyPI](https://pypi.org/project/pyannote.audio/3.1.1/), pyannote.audio 3.1.1 works with speaker-diarization-3.1. So, it\u2019s necessary to explicitly specify this version in the code.\n\n### To Reproduce\n\n1. Set up the environment. (I'm using torch 2.2.2+cu121.)\r\n2. Install so-vits-svc-fork and its dependencies.\r\n3. Install pyannote.audio with `pip3 install pyannote-audio`.\r\n4. Prepare your data and organize data folders.\r\n5. Run svc pre-sd with options suited to your data.\n\n### Additional context\n\n_No response_\n\n### Version\n\n4.1.61\n\n### Platform\n\nWSL-Ubuntu 22.04 LTS\n\n### Code of Conduct\n\n- [X] I agree to follow this project's Code of Conduct.\n\n### No Duplicate\n\n- [X] I have checked existing issues to avoid duplicates.\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom collections import defaultdict\nfrom logging import getLogger\nfrom pathlib import Path\n\nimport librosa\nimport soundfile as sf\nimport torch\nfrom joblib import Parallel, delayed\nfrom pyannote.audio import Pipeline\nfrom tqdm import tqdm\nfrom tqdm_joblib import tqdm_joblib\n\nLOG = getLogger(__name__)\n\n\ndef _process_one(\n    input_path: Path,\n    output_dir: Path,\n    sr: int,\n    *,\n    min_speakers: int = 1,\n    max_speakers: int = 1,\n    huggingface_token: str | None = None,\n) -> None:\n    try:\n        audio, sr = librosa.load(input_path, sr=sr, mono=True)\n    except Exception as e:\n        LOG.warning(f\"Failed to read {input_path}: {e}\")\n        return\n    pipeline = Pipeline.from_pretrained(\n        \"pyannote/speaker-diarization\", use_auth_token=huggingface_token\n    )\n    if pipeline is None:\n        raise ValueError(\"Failed to load pipeline\")\n    pipeline = pipeline.to(torch.device(\"cuda\"))\n    LOG.info(f\"Processing {input_path}. This may take a while...\")\n    diarization = pipeline(\n        input_path, min_speakers=min_speakers, max_speakers=max_speakers\n    )\n\n    LOG.info(f\"Found {len(diarization)} tracks, writing to {output_dir}\")\n    speaker_count = defaultdict(int)\n\n    output_dir.mkdir(parents=True, exist_ok=True)\n    for segment, track, speaker in tqdm(\n        list(diarization.itertracks(yield_label=True)), desc=f\"Writing {input_path}\"\n    ):\n        if segment.end - segment.start < 1:\n            continue\n        speaker_count[speaker] += 1\n        audio_cut = audio[int(segment.start * sr) : int(segment.end * sr)]\n        sf.write(\n            (output_dir / f\"{speaker}_{speaker_count[speaker]}.wav\"),\n            audio_cut,\n            sr,\n        )\n\n    LOG.info(f\"Speaker count: {speaker_count}\")\n\n\ndef preprocess_speaker_diarization(\n    input_dir: Path | str,\n    output_dir: Path | str,\n    sr: int,\n    *,\n    min_speakers: int = 1,\n    max_speakers: int = 1,\n    huggingface_token: str | None = None,\n    n_jobs: int = -1,\n) -> None:\n    if huggingface_token is not None and not huggingface_token.startswith(\"hf_\"):\n        LOG.warning(\"Huggingface token probably should start with hf_\")\n    if not torch.cuda.is_available():\n        LOG.warning(\"CUDA is not available. This will be extremely slow.\")\n    input_dir = Path(input_dir)\n    output_dir = Path(output_dir)\n    input_dir.mkdir(parents=True, exist_ok=True)\n    output_dir.mkdir(parents=True, exist_ok=True)\n    input_paths = list(input_dir.rglob(\"*.*\"))\n    with tqdm_joblib(desc=\"Preprocessing speaker diarization\", total=len(input_paths)):\n        Parallel(n_jobs=n_jobs)(\n            delayed(_process_one)(\n                input_path,\n                output_dir / input_path.relative_to(input_dir).parent / input_path.stem,\n                sr,\n                max_speakers=max_speakers,\n                min_speakers=min_speakers,\n                huggingface_token=huggingface_token,\n            )\n            for input_path in input_paths\n        )\n", "path": "src/so_vits_svc_fork/preprocessing/preprocess_speaker_diarization.py"}]}