├── .env
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── PULL_REQUEST_TEMPLATE.md
└── workflows
│ ├── checksum.yml
│ ├── close-issue.yml
│ ├── docker.yml
│ ├── genlocale.yml
│ ├── pull_format.yml
│ ├── push_format.yml
│ └── unitest.yml
├── .gitignore
├── Dockerfile
├── LICENSE
├── README.md
├── assets
├── hubert
│ └── .gitignore
├── indices
│ └── .gitignore
├── pretrained
│ └── .gitignore
├── pretrained_v2
│ └── .gitignore
├── rmvpe
│ └── .gitignore
├── uvr5_weights
│ └── .gitignore
└── weights
│ └── .gitignore
├── configs
├── __init__.py
├── config.json
├── config.py
├── inuse
│ ├── .gitignore
│ ├── v1
│ │ └── .gitignore
│ └── v2
│ │ └── .gitignore
├── v1
│ ├── 32k.json
│ ├── 40k.json
│ └── 48k.json
└── v2
│ ├── 32k.json
│ └── 48k.json
├── docker-compose.yml
├── docs
├── cn
│ ├── README.cn.md
│ └── faq.md
├── en
│ ├── README.en.md
│ ├── faiss_tips_en.md
│ ├── faq_en.md
│ └── training_tips_en.md
├── fr
│ ├── README.fr.md
│ ├── faiss_tips_fr.md
│ ├── faq_fr.md
│ └── training_tips_fr.md
├── jp
│ ├── README.ja.md
│ ├── faiss_tips_ja.md
│ ├── faq_ja.md
│ └── training_tips_ja.md
├── kr
│ ├── README.ko.han.md
│ ├── README.ko.md
│ ├── faiss_tips_ko.md
│ ├── faq_ko.md
│ └── training_tips_ko.md
├── pt
│ ├── README.pt.md
│ ├── faiss_tips_pt.md
│ ├── faq_pt.md
│ └── training_tips_pt.md
└── tr
│ ├── README.tr.md
│ ├── faiss_tips_tr.md
│ ├── faq_tr.md
│ └── training_tips_tr.md
├── gui.py
├── i18n
├── i18n.py
├── locale
│ ├── en_US.json
│ ├── es_ES.json
│ ├── fr_FR.json
│ ├── it_IT.json
│ ├── ja_JP.json
│ ├── ko_KR.json
│ ├── pt_BR.json
│ ├── ru_RU.json
│ ├── tr_TR.json
│ ├── zh_CN.json
│ ├── zh_HK.json
│ ├── zh_SG.json
│ └── zh_TW.json
├── locale_diff.py
└── scan_i18n.py
├── infer
├── lib
│ ├── audio.py
│ ├── rtrvc.py
│ ├── rvcmd.py
│ ├── slicer2.py
│ ├── train
│ │ ├── data_utils.py
│ │ ├── losses.py
│ │ ├── mel_processing.py
│ │ ├── process_ckpt.py
│ │ └── utils.py
│ └── uvr5_pack
│ │ ├── lib_v5
│ │ ├── layers.py
│ │ ├── layers_123821KB.py
│ │ ├── layers_33966KB.py
│ │ ├── layers_537238KB.py
│ │ ├── model_param_init.py
│ │ ├── modelparams
│ │ │ ├── 1band_sr16000_hl512.json
│ │ │ ├── 1band_sr32000_hl512.json
│ │ │ ├── 1band_sr33075_hl384.json
│ │ │ ├── 1band_sr44100_hl1024.json
│ │ │ ├── 1band_sr44100_hl256.json
│ │ │ ├── 1band_sr44100_hl512.json
│ │ │ ├── 1band_sr44100_hl512_cut.json
│ │ │ ├── 2band_32000.json
│ │ │ ├── 2band_44100_lofi.json
│ │ │ ├── 2band_48000.json
│ │ │ ├── 3band_44100.json
│ │ │ ├── 3band_44100_mid.json
│ │ │ ├── 3band_44100_msb2.json
│ │ │ ├── 4band_44100.json
│ │ │ ├── 4band_44100_mid.json
│ │ │ ├── 4band_44100_msb.json
│ │ │ ├── 4band_44100_msb2.json
│ │ │ ├── 4band_44100_reverse.json
│ │ │ ├── 4band_44100_sw.json
│ │ │ ├── 4band_v2.json
│ │ │ ├── 4band_v2_sn.json
│ │ │ ├── 4band_v3.json
│ │ │ └── ensemble.json
│ │ ├── nets.py
│ │ ├── nets_123821KB.py
│ │ ├── nets_33966KB.py
│ │ ├── nets_537238KB.py
│ │ └── spec_utils.py
│ │ ├── name_params.json
│ │ └── utils.py
└── modules
│ ├── gui
│ ├── __init__.py
│ ├── torchgate.py
│ └── utils.py
│ ├── train
│ ├── extract_f0_print.py
│ ├── extract_feature_print.py
│ ├── preprocess.py
│ └── train.py
│ ├── uvr5
│ ├── mdxnet.py
│ ├── modules.py
│ └── vr.py
│ └── vc
│ ├── __init__.py
│ ├── hash.py
│ ├── info.py
│ ├── lgdsng.npz
│ ├── modules.py
│ ├── pipeline.py
│ └── utils.py
├── logs
└── mute
│ ├── 0_gt_wavs
│ ├── mute32k.wav
│ ├── mute40k.wav
│ └── mute48k.wav
│ ├── 1_16k_wavs
│ └── mute.wav
│ ├── 2a_f0
│ └── mute.wav.npy
│ ├── 2b-f0nsf
│ └── mute.wav.npy
│ ├── 3_feature256
│ └── mute.npy
│ └── 3_feature768
│ └── mute.npy
├── requirements
├── amd.txt
├── dml.txt
├── gui-dml.txt
├── gui.txt
├── ipex.txt
├── main.txt
└── py311.txt
├── run.sh
├── rvc
├── __init__.py
├── f0
│ ├── __init__.py
│ ├── crepe.py
│ ├── deepunet.py
│ ├── dio.py
│ ├── e2e.py
│ ├── f0.py
│ ├── fcpe.py
│ ├── gen.py
│ ├── harvest.py
│ ├── mel.py
│ ├── models.py
│ ├── pm.py
│ ├── rmvpe.py
│ └── stft.py
├── hubert.py
├── ipex
│ ├── __init__.py
│ ├── attention.py
│ ├── gradscaler.py
│ ├── hijacks.py
│ └── init.py
├── jit
│ ├── __init__.py
│ └── jit.py
├── layers
│ ├── __init__.py
│ ├── attentions.py
│ ├── discriminators.py
│ ├── encoders.py
│ ├── generators.py
│ ├── norms.py
│ ├── nsf.py
│ ├── residuals.py
│ ├── synthesizers.py
│ ├── transforms.py
│ └── utils.py
├── onnx
│ ├── __init__.py
│ ├── exporter.py
│ ├── infer.py
│ └── synthesizer.py
└── synthesizer.py
├── sha256.env
├── tools
├── checksum
│ ├── main.go
│ └── tmpl.go
├── cmd
│ ├── calc_rvc_model_similarity.py
│ ├── infer-pm-index256.py
│ ├── infer_batch_rvc.py
│ ├── infer_cli.py
│ ├── onnx
│ │ ├── export.py
│ │ └── infer.py
│ ├── train-index-v2.py
│ ├── train-index.py
│ └── trans_weights.py
└── web
│ └── infer-only.py
└── web.py
/.env:
--------------------------------------------------------------------------------
1 | OPENBLAS_NUM_THREADS = 1
2 | no_proxy = localhost, 127.0.0.1, ::1
3 |
4 | # You can change the location of the model, etc. by changing here
5 | weight_root = assets/weights
6 | weight_uvr5_root = assets/uvr5_weights
7 | index_root = logs
8 | outside_index_root = assets/indices
9 | rmvpe_root = assets/rmvpe
10 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS and version: [e.g. Windows, Linux]
28 | - Python version: [e.g. 3.9.7, 3.11]
29 | - Commit/Tag with the issue: [e.g. 22]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | # Pull request checklist
2 |
3 | - [ ] The PR has a proper title. Use [Semantic Commit Messages](https://seesparkbox.com/foundry/semantic_commit_messages). (No more branch-name title please)
4 | - [ ] Make sure you are requesting the right branch: `dev`.
5 | - [ ] Make sure this is ready to be merged into the relevant branch. Please don't create a PR and let it hang for a few days.
6 | - [ ] Ensure all tests are passing.
7 | - [ ] Ensure linting is passing.
8 |
9 | # PR type
10 |
11 | - Bug fix / new feature / chore
12 |
13 | # Description
14 |
15 | - Describe what this pull request is for.
16 | - What will it affect.
17 |
18 | # Screenshot
19 |
20 | - Please include a screenshot if applicable
21 |
--------------------------------------------------------------------------------
/.github/workflows/checksum.yml:
--------------------------------------------------------------------------------
1 | name: Calculate and Sync SHA256
2 | on:
3 | push:
4 | branches:
5 | - main
6 | - dev
7 | jobs:
8 | checksum:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@master
12 |
13 | - name: Setup Go Environment
14 | uses: actions/setup-go@master
15 |
16 | - name: Run RVC-Models-Downloader
17 | run: |
18 | wget https://github.com/fumiama/RVC-Models-Downloader/releases/download/v0.2.5/rvcmd_linux_amd64.deb
19 | sudo apt -y install ./rvcmd_linux_amd64.deb
20 | rm -f ./rvcmd_linux_amd64.deb
21 | rvcmd -notrs -w 1 -notui assets/rvc
22 |
23 | - name: Calculate all Checksums
24 | run: go run tools/checksum/*.go
25 |
26 | - name: Commit back
27 | if: ${{ !github.head_ref }}
28 | id: commitback
29 | continue-on-error: true
30 | run: |
31 | git config --local user.name 'github-actions[bot]'
32 | git config --local user.email 'github-actions[bot]@users.noreply.github.com'
33 | git add --all
34 | git commit -m "chore(env): sync checksum on ${{github.ref_name}}"
35 |
36 | - name: Create Pull Request
37 | if: steps.commitback.outcome == 'success'
38 | continue-on-error: true
39 | uses: peter-evans/create-pull-request@v5
40 | with:
41 | delete-branch: true
42 | body: "Automatically sync checksum in .env"
43 | title: "chore(env): sync checksum on ${{github.ref_name}}"
44 | commit-message: "chore(env): sync checksum on ${{github.ref_name}}"
45 | branch: checksum-${{github.ref_name}}
46 |
--------------------------------------------------------------------------------
/.github/workflows/close-issue.yml:
--------------------------------------------------------------------------------
1 | name: Close Inactive Issues
2 | on:
3 | schedule:
4 | - cron: "0 4 * * *"
5 |
6 | jobs:
7 | close-issues:
8 | runs-on: ubuntu-latest
9 | permissions:
10 | issues: write
11 | pull-requests: write
12 | steps:
13 | - uses: actions/stale@v5
14 | with:
15 | exempt-issue-labels: "help wanted,good first issue,documentation,following up,todo list"
16 | days-before-issue-stale: 30
17 | days-before-issue-close: 15
18 | stale-issue-label: "stale"
19 | close-issue-message: "This issue was closed because it has been inactive for 15 days since being marked as stale."
20 | days-before-pr-stale: -1
21 | days-before-pr-close: -1
22 | operations-per-run: 10000
23 | repo-token: ${{ secrets.GITHUB_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.github/workflows/docker.yml:
--------------------------------------------------------------------------------
1 | name: Build and Push Docker Image
2 |
3 | on:
4 | workflow_dispatch:
5 | push:
6 | # Sequence of patterns matched against refs/tags
7 | tags:
8 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | permissions:
14 | packages: write
15 | contents: read
16 | steps:
17 | - uses: actions/checkout@v3
18 | - name: Set time zone
19 | uses: szenius/set-timezone@v1.0
20 | with:
21 | timezoneLinux: "Asia/Shanghai"
22 | timezoneMacos: "Asia/Shanghai"
23 | timezoneWindows: "China Standard Time"
24 |
25 | # # 如果有 dockerhub 账户,可以在github的secrets中配置下面两个,然后取消下面注释的这几行,并在meta步骤的images增加一行 ${{ github.repository }}
26 | # - name: Login to DockerHub
27 | # uses: docker/login-action@v1
28 | # with:
29 | # username: ${{ secrets.DOCKERHUB_USERNAME }}
30 | # password: ${{ secrets.DOCKERHUB_TOKEN }}
31 |
32 | - name: Login to GHCR
33 | uses: docker/login-action@v2
34 | with:
35 | registry: ghcr.io
36 | username: ${{ github.repository_owner }}
37 | password: ${{ secrets.GITHUB_TOKEN }}
38 |
39 | - name: Extract metadata (tags, labels) for Docker
40 | id: meta
41 | uses: docker/metadata-action@v4
42 | with:
43 | images: |
44 | ghcr.io/${{ github.repository }}
45 | # generate Docker tags based on the following events/attributes
46 | # nightly, master, pr-2, 1.2.3, 1.2, 1
47 | tags: |
48 | type=schedule,pattern=nightly
49 | type=edge
50 | type=ref,event=branch
51 | type=ref,event=pr
52 | type=semver,pattern={{version}}
53 | type=semver,pattern={{major}}.{{minor}}
54 | type=semver,pattern={{major}}
55 |
56 | - name: Set up QEMU
57 | uses: docker/setup-qemu-action@v2
58 |
59 | - name: Set up Docker Buildx
60 | uses: docker/setup-buildx-action@v2
61 |
62 | - name: Build and push
63 | id: docker_build
64 | uses: docker/build-push-action@v4
65 | with:
66 | context: .
67 | platforms: linux/amd64,linux/arm64
68 | push: true
69 | tags: ${{ steps.meta.outputs.tags }}
70 | labels: ${{ steps.meta.outputs.labels }}
71 |
--------------------------------------------------------------------------------
/.github/workflows/genlocale.yml:
--------------------------------------------------------------------------------
1 | name: Generate and Sync Locale
2 | on:
3 | push:
4 | branches:
5 | - main
6 | - dev
7 | jobs:
8 | genlocale:
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@master
12 |
13 | - name: Run locale generation
14 | run: |
15 | python3 i18n/scan_i18n.py
16 | cd i18n
17 | python3 locale_diff.py
18 |
19 | - name: Commit back
20 | if: ${{ !github.head_ref }}
21 | id: commitback
22 | continue-on-error: true
23 | run: |
24 | git config --local user.name 'github-actions[bot]'
25 | git config --local user.email 'github-actions[bot]@users.noreply.github.com'
26 | git add --all
27 | git commit -m "chore(i18n): sync locale on ${{github.ref_name}}"
28 |
29 | - name: Create Pull Request
30 | if: steps.commitback.outcome == 'success'
31 | continue-on-error: true
32 | uses: peter-evans/create-pull-request@v5
33 | with:
34 | delete-branch: true
35 | body: "Automatically sync i18n translation jsons"
36 | title: "chore(i18n): sync locale on ${{github.ref_name}}"
37 | commit-message: "chore(i18n): sync locale on ${{github.ref_name}}"
38 | branch: genlocale-${{github.ref_name}}
39 |
--------------------------------------------------------------------------------
/.github/workflows/pull_format.yml:
--------------------------------------------------------------------------------
1 | name: Check Pull Format
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened, reopened]
6 |
7 | jobs:
8 | # This workflow closes invalid PR
9 | close_pr:
10 | # The type of runner that the job will run on
11 | runs-on: ubuntu-latest
12 | permissions: write-all
13 |
14 | # Steps represent a sequence of tasks that will be executed as part of the job
15 | steps:
16 | - name: Close PR if it is not pointed to dev branch
17 | if: github.event.pull_request.base.ref != 'dev'
18 | uses: superbrothers/close-pull-request@v3
19 | with:
20 | # Optional. Post a issue comment just before closing a pull request.
21 | comment: "Invalid PR to `non-dev` branch `${{ github.event.pull_request.base.ref }}`."
22 |
23 | pull_format:
24 | runs-on: ubuntu-latest
25 | permissions:
26 | contents: write
27 |
28 | continue-on-error: true
29 |
30 | steps:
31 | - name: Checkout
32 | continue-on-error: true
33 | uses: actions/checkout@v3
34 | with:
35 | ref: ${{ github.head_ref }}
36 | fetch-depth: 0
37 |
38 | - name: Set up Python ${{ matrix.python-version }}
39 | uses: actions/setup-python@v4
40 | with:
41 | python-version: ${{ matrix.python-version }}
42 |
43 | - name: Install Black
44 | run: pip install "black[jupyter]"
45 |
46 | - name: Run Black
47 | # run: black $(git ls-files '*.py')
48 | run: black .
49 |
--------------------------------------------------------------------------------
/.github/workflows/push_format.yml:
--------------------------------------------------------------------------------
1 | name: Standardize Code Format
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | - dev
8 |
9 | jobs:
10 | push_format:
11 | runs-on: ubuntu-latest
12 |
13 | permissions:
14 | contents: write
15 | pull-requests: write
16 |
17 | steps:
18 | - uses: actions/checkout@v3
19 | with:
20 | ref: ${{github.ref_name}}
21 |
22 | - name: Set up Python ${{ matrix.python-version }}
23 | uses: actions/setup-python@v4
24 | with:
25 | python-version: ${{ matrix.python-version }}
26 |
27 | - name: Install Black
28 | run: pip install "black[jupyter]"
29 |
30 | - name: Run Black
31 | # run: black $(git ls-files '*.py')
32 | run: black .
33 |
34 | - name: Commit Back
35 | continue-on-error: true
36 | id: commitback
37 | run: |
38 | git config --local user.email "github-actions[bot]@users.noreply.github.com"
39 | git config --local user.name "github-actions[bot]"
40 | git add --all
41 | git commit -m "chore(format): run black on ${{github.ref_name}}"
42 |
43 | - name: Create Pull Request
44 | if: steps.commitback.outcome == 'success'
45 | continue-on-error: true
46 | uses: peter-evans/create-pull-request@v5
47 | with:
48 | delete-branch: true
49 | body: "Automatically apply code formatter change"
50 | title: "chore(format): run black on ${{github.ref_name}}"
51 | commit-message: "chore(format): run black on ${{github.ref_name}}"
52 | branch: formatter-${{github.ref_name}}
53 |
--------------------------------------------------------------------------------
/.github/workflows/unitest.yml:
--------------------------------------------------------------------------------
1 | name: Unit Test
2 | on: [ push, pull_request ]
3 | jobs:
4 | build:
5 | runs-on: ${{ matrix.os }}
6 | strategy:
7 | matrix:
8 | python-version: ["3.8", "3.9", "3.10"]
9 | os: [ubuntu-latest]
10 | fail-fast: true
11 |
12 | steps:
13 | - uses: actions/checkout@master
14 | - name: Set up Python ${{ matrix.python-version }}
15 | uses: actions/setup-python@v4
16 | with:
17 | python-version: ${{ matrix.python-version }}
18 | - name: Install dependencies
19 | run: |
20 | sudo apt update
21 | wget https://github.com/fumiama/RVC-Models-Downloader/releases/download/v0.2.5/rvcmd_linux_amd64.deb
22 | sudo apt -y install ./rvcmd_linux_amd64.deb
23 | pip install --force pip==24.0 # fix fairseq installing issue https://github.com/facebookresearch/fairseq/issues/5552
24 | python -m pip install --upgrade setuptools
25 | python -m pip install --upgrade wheel
26 | pip install torch torchvision torchaudio
27 | pip install -r requirements/main.txt
28 | rvcmd -notrs -w 1 -notui assets/rvc
29 | - name: Test step 1 & 2
30 | run: |
31 | mkdir -p logs/mi-test
32 | touch logs/mi-test/preprocess.log
33 | python infer/modules/train/preprocess.py logs/mute/0_gt_wavs 48000 8 logs/mi-test True 3.7
34 | touch logs/mi-test/extract_f0_feature.log
35 | python infer/modules/train/extract_f0_print.py logs/mi-test $(nproc) pm cpu False
36 | python infer/modules/train/extract_feature_print.py cpu 1 0 0 logs/mi-test v1 True
37 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | __pycache__
3 | /TEMP
4 | *.pyd
5 | .venv
6 | .vscode
7 | .idea
8 | xcuserdata
9 | /opt
10 |
11 | # Generated by RVC
12 | /logs
13 |
14 | /assets/weights/*
15 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax=docker/dockerfile:1
2 |
3 | FROM nvidia/cuda:11.6.2-cudnn8-runtime-ubuntu20.04
4 |
5 | EXPOSE 7865
6 |
7 | WORKDIR /app
8 |
9 | # Install dependenceis to add PPAs
10 | RUN apt-get update && \
11 | apt-get install -y -qq aria2 && apt clean && \
12 | apt-get install -y software-properties-common && \
13 | apt-get clean && \
14 | rm -rf /var/lib/apt/lists/*
15 | # Add the deadsnakes PPA to get Python 3.9
16 | RUN add-apt-repository ppa:deadsnakes/ppa
17 |
18 | # Install Python 3.9 and pip
19 | RUN apt-get update && \
20 | apt-get install -y build-essential python-dev python3-dev python3.9-distutils python3.9-dev python3.9 curl && \
21 | apt-get clean && \
22 | update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.9 1 && \
23 | curl https://bootstrap.pypa.io/get-pip.py | python3.9
24 |
25 | # Set Python 3.9 as the default
26 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.9 1
27 |
28 | COPY . .
29 |
30 | RUN python3 -m pip install --upgrade pip>=24.0
31 | RUN python3 -m pip install --no-cache-dir -r requirements/main.txt
32 |
33 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/pretrained_v2/D40k.pth -d assets/pretrained_v2/ -o D40k.pth
34 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/pretrained_v2/G40k.pth -d assets/pretrained_v2/ -o G40k.pth
35 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/pretrained_v2/f0D40k.pth -d assets/pretrained_v2/ -o f0D40k.pth
36 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/pretrained_v2/f0G40k.pth -d assets/pretrained_v2/ -o f0G40k.pth
37 |
38 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/uvr5_weights/HP2-人声vocals+非人声instrumentals.pth -d assets/uvr5_weights/ -o HP2-人声vocals+非人声instrumentals.pth
39 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/uvr5_weights/HP5-主旋律人声vocals+其他instrumentals.pth -d assets/uvr5_weights/ -o HP5-主旋律人声vocals+其他instrumentals.pth
40 |
41 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/hubert_base.pt -d assets/hubert -o hubert_base.pt
42 |
43 | RUN aria2c --console-log-level=error -c -x 16 -s 16 -k 1M https://huggingface.co/lj1995/VoiceConversionWebUI/resolve/main/rmvpe.pt -d assets/rmvpe -o rmvpe.pt
44 |
45 | VOLUME [ "/app/weights", "/app/opt" ]
46 |
47 | CMD ["python3", "web.py"]
48 |
--------------------------------------------------------------------------------
/assets/hubert/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/indices/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/pretrained/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/pretrained_v2/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/rmvpe/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/uvr5_weights/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/assets/weights/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/configs/__init__.py:
--------------------------------------------------------------------------------
1 | from .config import singleton_variable, Config, CPUConfig
2 |
--------------------------------------------------------------------------------
/configs/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "pth_path": "",
3 | "index_path": "",
4 | "sg_hostapi": "MME",
5 | "sg_wasapi_exclusive": false,
6 | "sg_input_device": "",
7 | "sg_output_device": "",
8 | "sr_type": "sr_device",
9 | "threhold": -60.0,
10 | "pitch": 12.0,
11 | "formant": 0.0,
12 | "rms_mix_rate": 0.5,
13 | "index_rate": 0.0,
14 | "block_time": 0.15,
15 | "crossfade_length": 0.08,
16 | "extra_time": 2.0,
17 | "n_cpu": 4.0,
18 | "use_jit": false,
19 | "use_pv": false,
20 | "f0method": "fcpe"
21 | }
--------------------------------------------------------------------------------
/configs/inuse/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 | !v1
4 | !v2
5 |
--------------------------------------------------------------------------------
/configs/inuse/v1/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/configs/inuse/v2/.gitignore:
--------------------------------------------------------------------------------
1 | *
2 | !.gitignore
3 |
--------------------------------------------------------------------------------
/configs/v1/32k.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "seed": 1234,
5 | "epochs": 20000,
6 | "learning_rate": 1e-4,
7 | "betas": [0.8, 0.99],
8 | "eps": 1e-9,
9 | "batch_size": 4,
10 | "fp16_run": true,
11 | "lr_decay": 0.999875,
12 | "segment_size": 12800,
13 | "init_lr_ratio": 1,
14 | "warmup_epochs": 0,
15 | "c_mel": 45,
16 | "c_kl": 1.0
17 | },
18 | "data": {
19 | "max_wav_value": 32768.0,
20 | "sampling_rate": 32000,
21 | "filter_length": 1024,
22 | "hop_length": 320,
23 | "win_length": 1024,
24 | "n_mel_channels": 80,
25 | "mel_fmin": 0.0,
26 | "mel_fmax": null
27 | },
28 | "model": {
29 | "inter_channels": 192,
30 | "hidden_channels": 192,
31 | "filter_channels": 768,
32 | "n_heads": 2,
33 | "n_layers": 6,
34 | "kernel_size": 3,
35 | "p_dropout": 0,
36 | "resblock": "1",
37 | "resblock_kernel_sizes": [3,7,11],
38 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
39 | "upsample_rates": [10,4,2,2,2],
40 | "upsample_initial_channel": 512,
41 | "upsample_kernel_sizes": [16,16,4,4,4],
42 | "use_spectral_norm": false,
43 | "gin_channels": 256,
44 | "spk_embed_dim": 109
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/configs/v1/40k.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "seed": 1234,
5 | "epochs": 20000,
6 | "learning_rate": 1e-4,
7 | "betas": [0.8, 0.99],
8 | "eps": 1e-9,
9 | "batch_size": 4,
10 | "fp16_run": true,
11 | "lr_decay": 0.999875,
12 | "segment_size": 12800,
13 | "init_lr_ratio": 1,
14 | "warmup_epochs": 0,
15 | "c_mel": 45,
16 | "c_kl": 1.0
17 | },
18 | "data": {
19 | "max_wav_value": 32768.0,
20 | "sampling_rate": 40000,
21 | "filter_length": 2048,
22 | "hop_length": 400,
23 | "win_length": 2048,
24 | "n_mel_channels": 125,
25 | "mel_fmin": 0.0,
26 | "mel_fmax": null
27 | },
28 | "model": {
29 | "inter_channels": 192,
30 | "hidden_channels": 192,
31 | "filter_channels": 768,
32 | "n_heads": 2,
33 | "n_layers": 6,
34 | "kernel_size": 3,
35 | "p_dropout": 0,
36 | "resblock": "1",
37 | "resblock_kernel_sizes": [3,7,11],
38 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
39 | "upsample_rates": [10,10,2,2],
40 | "upsample_initial_channel": 512,
41 | "upsample_kernel_sizes": [16,16,4,4],
42 | "use_spectral_norm": false,
43 | "gin_channels": 256,
44 | "spk_embed_dim": 109
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/configs/v1/48k.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "seed": 1234,
5 | "epochs": 20000,
6 | "learning_rate": 1e-4,
7 | "betas": [0.8, 0.99],
8 | "eps": 1e-9,
9 | "batch_size": 4,
10 | "fp16_run": true,
11 | "lr_decay": 0.999875,
12 | "segment_size": 11520,
13 | "init_lr_ratio": 1,
14 | "warmup_epochs": 0,
15 | "c_mel": 45,
16 | "c_kl": 1.0
17 | },
18 | "data": {
19 | "max_wav_value": 32768.0,
20 | "sampling_rate": 48000,
21 | "filter_length": 2048,
22 | "hop_length": 480,
23 | "win_length": 2048,
24 | "n_mel_channels": 128,
25 | "mel_fmin": 0.0,
26 | "mel_fmax": null
27 | },
28 | "model": {
29 | "inter_channels": 192,
30 | "hidden_channels": 192,
31 | "filter_channels": 768,
32 | "n_heads": 2,
33 | "n_layers": 6,
34 | "kernel_size": 3,
35 | "p_dropout": 0,
36 | "resblock": "1",
37 | "resblock_kernel_sizes": [3,7,11],
38 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
39 | "upsample_rates": [10,6,2,2,2],
40 | "upsample_initial_channel": 512,
41 | "upsample_kernel_sizes": [16,16,4,4,4],
42 | "use_spectral_norm": false,
43 | "gin_channels": 256,
44 | "spk_embed_dim": 109
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/configs/v2/32k.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "seed": 1234,
5 | "epochs": 20000,
6 | "learning_rate": 1e-4,
7 | "betas": [0.8, 0.99],
8 | "eps": 1e-9,
9 | "batch_size": 4,
10 | "fp16_run": true,
11 | "lr_decay": 0.999875,
12 | "segment_size": 12800,
13 | "init_lr_ratio": 1,
14 | "warmup_epochs": 0,
15 | "c_mel": 45,
16 | "c_kl": 1.0
17 | },
18 | "data": {
19 | "max_wav_value": 32768.0,
20 | "sampling_rate": 32000,
21 | "filter_length": 1024,
22 | "hop_length": 320,
23 | "win_length": 1024,
24 | "n_mel_channels": 80,
25 | "mel_fmin": 0.0,
26 | "mel_fmax": null
27 | },
28 | "model": {
29 | "inter_channels": 192,
30 | "hidden_channels": 192,
31 | "filter_channels": 768,
32 | "n_heads": 2,
33 | "n_layers": 6,
34 | "kernel_size": 3,
35 | "p_dropout": 0,
36 | "resblock": "1",
37 | "resblock_kernel_sizes": [3,7,11],
38 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
39 | "upsample_rates": [10,8,2,2],
40 | "upsample_initial_channel": 512,
41 | "upsample_kernel_sizes": [20,16,4,4],
42 | "use_spectral_norm": false,
43 | "gin_channels": 256,
44 | "spk_embed_dim": 109
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/configs/v2/48k.json:
--------------------------------------------------------------------------------
1 | {
2 | "train": {
3 | "log_interval": 200,
4 | "seed": 1234,
5 | "epochs": 20000,
6 | "learning_rate": 1e-4,
7 | "betas": [0.8, 0.99],
8 | "eps": 1e-9,
9 | "batch_size": 4,
10 | "fp16_run": true,
11 | "lr_decay": 0.999875,
12 | "segment_size": 17280,
13 | "init_lr_ratio": 1,
14 | "warmup_epochs": 0,
15 | "c_mel": 45,
16 | "c_kl": 1.0
17 | },
18 | "data": {
19 | "max_wav_value": 32768.0,
20 | "sampling_rate": 48000,
21 | "filter_length": 2048,
22 | "hop_length": 480,
23 | "win_length": 2048,
24 | "n_mel_channels": 128,
25 | "mel_fmin": 0.0,
26 | "mel_fmax": null
27 | },
28 | "model": {
29 | "inter_channels": 192,
30 | "hidden_channels": 192,
31 | "filter_channels": 768,
32 | "n_heads": 2,
33 | "n_layers": 6,
34 | "kernel_size": 3,
35 | "p_dropout": 0,
36 | "resblock": "1",
37 | "resblock_kernel_sizes": [3,7,11],
38 | "resblock_dilation_sizes": [[1,3,5], [1,3,5], [1,3,5]],
39 | "upsample_rates": [12,10,2,2],
40 | "upsample_initial_channel": 512,
41 | "upsample_kernel_sizes": [24,20,4,4],
42 | "use_spectral_norm": false,
43 | "gin_channels": 256,
44 | "spk_embed_dim": 109
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: "3.8"
2 | services:
3 | rvc:
4 | build:
5 | context: .
6 | dockerfile: Dockerfile
7 | container_name: rvc
8 | volumes:
9 | - ./weights:/app/assets/weights
10 | - ./opt:/app/opt
11 | # - ./dataset:/app/dataset # you can use this folder in order to provide your dataset for model training
12 | ports:
13 | - 7865:7865
14 | deploy:
15 | resources:
16 | reservations:
17 | devices:
18 | - driver: nvidia
19 | count: 1
20 | capabilities: [gpu]
--------------------------------------------------------------------------------
/docs/cn/faq.md:
--------------------------------------------------------------------------------
1 | ## Q1:一键训练结束没有索引
2 |
3 | 显示"Training is done. The program is closed."则模型训练成功,后续紧邻的报错是假的;
4 |
5 |
6 | 一键训练结束完成没有added开头的索引文件,可能是因为训练集太大卡住了添加索引的步骤;已通过批处理add索引解决内存add索引对内存需求过大的问题。临时可尝试再次点击"训练索引"按钮。
7 |
8 |
9 | ## Q2:训练结束推理没看到训练集的音色
10 | 点刷新音色再看看,如果还没有看看训练有没有报错,控制台和webui的截图,logs/实验名下的log,都可以发给开发者看看。
11 |
12 |
13 | ## Q3:如何分享模型
14 | rvc_root/logs/实验名 下面存储的pth不是用来分享模型用来推理的,而是为了存储实验状态供复现,以及继续训练用的。用来分享的模型应该是weights文件夹下大小为60+MB的pth文件;
15 |
16 | 后续将把weights/exp_name.pth和logs/exp_name/added_xxx.index合并打包成weights/exp_name.zip省去填写index的步骤,那么zip文件用来分享,不要分享pth文件,除非是想换机器继续训练;
17 |
18 | 如果你把logs文件夹下的几百MB的pth文件复制/分享到weights文件夹下强行用于推理,可能会出现f0,tgt_sr等各种key不存在的报错。你需要用ckpt选项卡最下面,手工或自动(本地logs下如果能找到相关信息则会自动)选择是否携带音高、目标音频采样率的选项后进行ckpt小模型提取(输入路径填G开头的那个),提取完在weights文件夹下会出现60+MB的pth文件,刷新音色后可以选择使用。
19 |
20 |
21 | ## Q4:Connection Error.
22 | 也许你关闭了控制台(黑色窗口)。
23 |
24 |
25 | ## Q5:WebUI弹出Expecting value: line 1 column 1 (char 0).
26 | 请关闭系统局域网代理/全局代理。
27 |
28 |
29 | 这个不仅是客户端的代理,也包括服务端的代理(例如你使用autodl设置了http_proxy和https_proxy学术加速,使用时也需要unset关掉)
30 |
31 |
32 | ## Q6:不用WebUI如何通过命令训练推理
33 | 训练脚本:
34 |
35 | 可先跑通WebUI,消息窗内会显示数据集处理和训练用命令行;
36 |
37 |
38 | 推理脚本:
39 |
40 | https://huggingface.co/lj1995/VoiceConversionWebUI/blob/main/myinfer.py
41 |
42 |
43 | 例子:
44 |
45 |
46 | runtime\python.exe myinfer.py 0 "E:\codes\py39\RVC-beta\todo-songs\1111.wav" "E:\codes\py39\logs\mi-test\added_IVF677_Flat_nprobe_7.index" harvest "test.wav" "weights/mi-test.pth" 0.6 cuda:0 True
47 |
48 |
49 | f0up_key=sys.argv[1]
50 |
51 | input_path=sys.argv[2]
52 |
53 | index_path=sys.argv[3]
54 |
55 | f0method=sys.argv[4]#harvest or pm
56 |
57 | opt_path=sys.argv[5]
58 |
59 | model_path=sys.argv[6]
60 |
61 | index_rate=float(sys.argv[7])
62 |
63 | device=sys.argv[8]
64 |
65 | is_half=bool(sys.argv[9])
66 |
67 |
68 | ## Q7:Cuda error/Cuda out of memory.
69 | 小概率是cuda配置问题、设备不支持;大概率是显存不够(out of memory);
70 |
71 |
72 | 训练的话缩小batch size(如果缩小到1还不够只能更换显卡训练),推理的话酌情缩小config.py结尾的x_pad,x_query,x_center,x_max。4G以下显存(例如1060(3G)和各种2G显卡)可以直接放弃,4G显存显卡还有救。
73 |
74 |
75 | ## Q8:total_epoch调多少比较好
76 |
77 | 如果训练集音质差底噪大,20~30足够了,调太高,底模音质无法带高你的低音质训练集
78 |
79 | 如果训练集音质高底噪低时长多,可以调高,200是ok的(训练速度很快,既然你有条件准备高音质训练集,显卡想必条件也不错,肯定不在乎多一些训练时间)
80 |
81 |
82 | ## Q9:需要多少训练集时长
83 | 推荐10min至50min
84 |
85 | 保证音质高底噪低的情况下,如果有个人特色的音色统一,则多多益善
86 |
87 | 高水平的训练集(精简+音色有特色),5min至10min也是ok的,仓库作者本人就经常这么玩
88 |
89 | 也有人拿1min至2min的数据来训练并且训练成功的,但是成功经验是其他人不可复现的,不太具备参考价值。这要求训练集音色特色非常明显(比如说高频气声较明显的萝莉少女音),且音质高;
90 |
91 | 1min以下时长数据目前没见有人尝试(成功)过。不建议进行这种鬼畜行为。
92 |
93 |
94 | ## Q10:index rate干嘛用的,怎么调(科普)
95 | 如果底模和推理源的音质高于训练集的音质,他们可以带高推理结果的音质,但代价可能是音色往底模/推理源的音色靠,这种现象叫做"音色泄露";
96 |
97 | index rate用来削减/解决音色泄露问题。调到1,则理论上不存在推理源的音色泄露问题,但音质更倾向于训练集。如果训练集音质比推理源低,则index rate调高可能降低音质。调到0,则不具备利用检索混合来保护训练集音色的效果;
98 |
99 | 如果训练集优质时长多,可调高total_epoch,此时模型本身不太会引用推理源和底模的音色,很少存在"音色泄露"问题,此时index_rate不重要,你甚至可以不建立/分享index索引文件。
100 |
101 |
102 | ## Q11:推理怎么选gpu
103 | config.py文件里device cuda:后面选择卡号;
104 |
105 | 卡号和显卡的映射关系,在训练选项卡的显卡信息栏里能看到。
106 |
107 |
108 | ## Q12:如何推理训练中间保存的pth
109 | 通过ckpt选项卡最下面提取小模型。
110 |
111 |
112 |
113 | ## Q13:如何中断和继续训练
114 | 现阶段只能关闭WebUI控制台双击go-web.bat重启程序。网页参数也要刷新重新填写;
115 |
116 | 继续训练:相同网页参数点训练模型,就会接着上次的checkpoint继续训练。
117 |
118 |
119 | ## Q14:训练时出现文件页面/内存error
120 | 进程开太多了,内存炸了。你可能可以通过如下方式解决
121 |
122 | 1、"提取音高和处理数据使用的CPU进程数" 酌情拉低;
123 |
124 | 2、训练集音频手工切一下,不要太长。
125 |
126 |
127 |
128 | ## Q15:如何中途加数据训练
129 | 1、所有数据新建一个实验名;
130 |
131 | 2、拷贝上一次的最新的那个G和D文件(或者你想基于哪个中间ckpt训练,也可以拷贝中间的)到新实验名;下
132 |
133 | 3、一键训练新实验名,他会继续上一次的最新进度训练。
134 |
135 |
136 | ## Q16: error about llvmlite.dll
137 |
138 | OSError: Could not load shared object file: llvmlite.dll
139 |
140 | FileNotFoundError: Could not find module lib\site-packages\llvmlite\binding\llvmlite.dll (or one of its dependencies). Try using the full path with constructor syntax.
141 |
142 | win平台会报这个错,装上https://aka.ms/vs/17/release/vc_redist.x64.exe这个再重启WebUI就好了。
143 |
144 | ## Q17: RuntimeError: The expanded size of the tensor (17280) must match the existing size (0) at non-singleton dimension 1. Target sizes: [1, 17280]. Tensor sizes: [0]
145 |
146 | wavs16k文件夹下,找到文件大小显著比其他都小的一些音频文件,删掉,点击训练模型,就不会报错了,不过由于一键流程中断了你训练完模型还要点训练索引。
147 |
148 | ## Q18: RuntimeError: The size of tensor a (24) must match the size of tensor b (16) at non-singleton dimension 2
149 |
150 | 不要中途变更采样率继续训练。如果一定要变更,应更换实验名从头训练。当然你也可以把上次提取的音高和特征(0/1/2/2b folders)拷贝过去加速训练流程。
151 |
--------------------------------------------------------------------------------
/docs/en/training_tips_en.md:
--------------------------------------------------------------------------------
1 | Instructions and tips for RVC training
2 | ======================================
3 | This TIPS explains how data training is done.
4 |
5 | # Training flow
6 | I will explain along the steps in the training tab of the GUI.
7 |
8 | ## step1
9 | Set the experiment name here.
10 |
11 | You can also set here whether the model should take pitch into account.
12 | If the model doesn't consider pitch, the model will be lighter, but not suitable for singing.
13 |
14 | Data for each experiment is placed in `/logs/your-experiment-name/`.
15 |
16 | ## step2a
17 | Loads and preprocesses audio.
18 |
19 | ### load audio
20 | If you specify a folder with audio, the audio files in that folder will be read automatically.
21 | For example, if you specify `C:Users\hoge\voices`, `C:Users\hoge\voices\voice.mp3` will be loaded, but `C:Users\hoge\voices\dir\voice.mp3` will Not loaded.
22 |
23 | Since ffmpeg is used internally for reading audio, if the extension is supported by ffmpeg, it will be read automatically.
24 | After converting to int16 with ffmpeg, convert to float32 and normalize between -1 to 1.
25 |
26 | ### denoising
27 | The audio is smoothed by scipy's filtfilt.
28 |
29 | ### Audio Split
30 | First, the input audio is divided by detecting parts of silence that last longer than a certain period (max_sil_kept=5 seconds?). After splitting the audio on silence, split the audio every 4 seconds with an overlap of 0.3 seconds. For audio separated within 4 seconds, after normalizing the volume, convert the wav file to `/logs/your-experiment-name/0_gt_wavs` and then convert it to 16k sampling rate to `/logs/your-experiment-name/1_16k_wavs ` as a wav file.
31 |
32 | ## step2b
33 | ### Extract pitch
34 | Extract pitch information from wav files. Extract the pitch information (=f0) using the method built into parselmouth or pyworld and save it in `/logs/your-experiment-name/2a_f0`. Then logarithmically convert the pitch information to an integer between 1 and 255 and save it in `/logs/your-experiment-name/2b-f0nsf`.
35 |
36 | ### Extract feature_print
37 | Convert the wav file to embedding in advance using HuBERT. Read the wav file saved in `/logs/your-experiment-name/1_16k_wavs`, convert the wav file to 256-dimensional features with HuBERT, and save in npy format in `/logs/your-experiment-name/3_feature256`.
38 |
39 | ## step3
40 | train the model.
41 | ### Glossary for Beginners
42 | In deep learning, the data set is divided and the learning proceeds little by little. In one model update (step), batch_size data are retrieved and predictions and error corrections are performed. Doing this once for a dataset counts as one epoch.
43 |
44 | Therefore, the learning time is the learning time per step x (the number of data in the dataset / batch size) x the number of epochs. In general, the larger the batch size, the more stable the learning becomes (learning time per step ÷ batch size) becomes smaller, but it uses more GPU memory. GPU RAM can be checked with the nvidia-smi command. Learning can be done in a short time by increasing the batch size as much as possible according to the machine of the execution environment.
45 |
46 | ### Specify pretrained model
47 | RVC starts training the model from pretrained weights instead of from 0, so it can be trained with a small dataset.
48 |
49 | By default
50 |
51 | - If you consider pitch, it loads `rvc-location/pretrained/f0G40k.pth` and `rvc-location/pretrained/f0D40k.pth`.
52 | - If you don't consider pitch, it loads `rvc-location/pretrained/G40k.pth` and `rvc-location/pretrained/D40k.pth`.
53 |
54 | When learning, model parameters are saved in `logs/your-experiment-name/G_{}.pth` and `logs/your-experiment-name/D_{}.pth` for each save_every_epoch, but by specifying this path, you can start learning. You can restart or start training from model weights learned in a different experiment.
55 |
56 | ### learning index
57 | RVC saves the HuBERT feature values used during training, and during inference, searches for feature values that are similar to the feature values used during learning to perform inference. In order to perform this search at high speed, the index is learned in advance.
58 | For index learning, we use the approximate neighborhood search library faiss. Read the feature value of `logs/your-experiment-name/3_feature256` and use it to learn the index, and save it as `logs/your-experiment-name/add_XXX.index`.
59 |
60 | (From the 20230428update version, it is read from the index, and saving / specifying is no longer necessary.)
61 |
62 | ### Button description
63 | - Train model: After executing step2b, press this button to train the model.
64 | - Train feature index: After training the model, perform index learning.
65 | - One-click training: step2b, model training and feature index training all at once.
--------------------------------------------------------------------------------
/docs/jp/faiss_tips_ja.md:
--------------------------------------------------------------------------------
1 | faiss tuning TIPS
2 | ==================
3 | # about faiss
4 | faissはfacebook researchの開発する、密なベクトルに対する近傍探索をまとめたライブラリで、多くの近似近傍探索の手法を効率的に実装しています。
5 | 近似近傍探索はある程度精度を犠牲にしながら高速に類似するベクトルを探します。
6 |
7 | ## faiss in RVC
8 | RVCではHuBERTで変換した特徴量のEmbeddingに対し、学習データから生成されたEmbeddingと類似するものを検索し、混ぜることでより元の音声に近い変換を実現しています。ただ、この検索は愚直に行うと時間がかかるため、近似近傍探索を用いることで高速な変換を実現しています。
9 |
10 | # 実装のoverview
11 | モデルが配置されている '/logs/your-experiment/3_feature256'には各音声データからHuBERTで抽出された特徴量が配置されています。
12 | ここからnpyファイルをファイル名でソートした順番で読み込み、ベクトルを連結してbig_npyを作成しfaissを学習させます。(このベクトルのshapeは[N, 256]です。)
13 |
14 | 本Tipsではまずこれらのパラメータの意味を解説します。
15 |
16 | # 手法の解説
17 | ## index factory
18 | index factoryは複数の近似近傍探索の手法を繋げるパイプラインをstringで表記するfaiss独自の記法です。
19 | これにより、index factoryの文字列を変更するだけで様々な近似近傍探索の手法を試せます。
20 | RVCでは以下のように使われています。
21 |
22 | ```python
23 | index = faiss.index_factory(256, "IVF%s,Flat" % n_ivf)
24 | ```
25 | index_factoryの引数のうち、1つ目はベクトルの次元数、2つ目はindex factoryの文字列で、3つ目には用いる距離を指定することができます。
26 |
27 | より詳細な記法については
28 | https://github.com/facebookresearch/faiss/wiki/The-index-factory
29 |
30 | ## 距離指標
31 | embeddingの類似度として用いられる代表的な指標として以下の二つがあります。
32 |
33 | - ユークリッド距離(METRIC_L2)
34 | - 内積(METRIC_INNER_PRODUCT)
35 |
36 | ユークリッド距離では各次元において二乗の差をとり、全次元の差を足してから平方根をとります。これは日常的に用いる2次元、3次元での距離と同じです。
37 | 内積はこのままでは類似度の指標として用いず、一般的にはL2ノルムで正規化してから内積をとるコサイン類似度を用います。
38 |
39 | どちらがよいかは場合によりますが、word2vec等で得られるembeddingやArcFace等で学習した類似画像検索のモデルではコサイン類似度が用いられることが多いです。ベクトルXに対してl2正規化をnumpyで行う場合は、0 divisionを避けるために十分に小さな値をepsとして以下のコードで可能です。
40 |
41 | ```python
42 | X_normed = X / np.maximum(eps, np.linalg.norm(X, ord=2, axis=-1, keepdims=True))
43 | ```
44 |
45 | また、index factoryには第3引数に渡す値を選ぶことで計算に用いる距離指標を変更できます。
46 |
47 | ```python
48 | index = faiss.index_factory(dimention, text, faiss.METRIC_INNER_PRODUCT)
49 | ```
50 |
51 | ## IVF
52 | IVF(Inverted file indexes)は全文検索における転置インデックスと似たようなアルゴリズムです。
53 | 学習時には検索対象に対してkmeansでクラスタリングを行い、クラスタ中心を用いてボロノイ分割を行います。各データ点には一つずつクラスタが割り当てられるので、クラスタからデータ点を逆引きする辞書を作成します。
54 |
55 | 例えば以下のようにクラスタが割り当てられた場合
56 | |index|クラスタ|
57 | |-----|-------|
58 | |1|A|
59 | |2|B|
60 | |3|A|
61 | |4|C|
62 | |5|B|
63 |
64 | 作成される転置インデックスは以下のようになります。
65 |
66 | |クラスタ|index|
67 | |-------|-----|
68 | |A|1, 3|
69 | |B|2, 5|
70 | |C|4|
71 |
72 | 検索時にはまずクラスタからn_probe個のクラスタを検索し、次にそれぞれのクラスタに属するデータ点について距離を計算します。
73 |
74 | # 推奨されるパラメータ
75 | indexの選び方については公式にガイドラインがあるので、それに準じて説明します。
76 | https://github.com/facebookresearch/faiss/wiki/Guidelines-to-choose-an-index
77 |
78 | 1M以下のデータセットにおいては4bit-PQが2023年4月時点ではfaissで利用できる最も効率的な手法です。
79 | これをIVFと組み合わせ、4bit-PQで候補を絞り、最後に正確な指標で距離を再計算するには以下のindex factoryを用いることで記載できます。
80 |
81 | ```python
82 | index = faiss.index_factory(256, "IVF1024,PQ128x4fs,RFlat")
83 | ```
84 |
85 | ## IVFの推奨パラメータ
86 | IVFの数が多すぎる場合、たとえばデータ数の数だけIVFによる粗量子化を行うと、これは愚直な全探索と同じになり効率が悪いです。
87 | 1M以下の場合ではIVFの値はデータ点の数Nに対して4*sqrt(N) ~ 16*sqrt(N)に推奨しています。
88 |
89 | n_probeはn_probeの数に比例して計算時間が増えるので、精度と相談して適切に選んでください。個人的にはRVCにおいてそこまで精度は必要ないと思うのでn_probe = 1で良いと思います。
90 |
91 | ## FastScan
92 | FastScanは直積量子化で大まかに距離を近似するのを、レジスタ内で行うことにより高速に行うようにした手法です。
93 | 直積量子化は学習時にd次元ごと(通常はd=2)に独立してクラスタリングを行い、クラスタ同士の距離を事前計算してlookup tableを作成します。予測時はlookup tableを見ることで各次元の距離をO(1)で計算できます。
94 | そのため、PQの次に指定する数字は通常ベクトルの半分の次元を指定します。
95 |
96 | FastScanに関するより詳細な説明は公式のドキュメントを参照してください。
97 | https://github.com/facebookresearch/faiss/wiki/Fast-accumulation-of-PQ-and-AQ-codes-(FastScan)
98 |
99 | ## RFlat
100 | RFlatはFastScanで計算した大まかな距離を、index factoryの第三引数で指定した正確な距離で再計算する指示です。
101 | k個の近傍を取得する際は、k*k_factor個の点について再計算が行われます。
102 |
--------------------------------------------------------------------------------
/docs/jp/training_tips_ja.md:
--------------------------------------------------------------------------------
1 | RVCの訓練における説明、およびTIPS
2 | ===============================
3 | 本TIPSではどのようにデータの訓練が行われているかを説明します。
4 |
5 | # 訓練の流れ
6 | GUIの訓練タブのstepに沿って説明します。
7 |
8 | ## step1
9 | 実験名の設定を行います。
10 |
11 | また、モデルに音高ガイド(ピッチ)を考慮させるかもここで設定できます。考慮させない場合はモデルは軽量になりますが、歌唱には向かなくなります。
12 |
13 | 各実験のデータは`/logs/実験名/`に配置されます。
14 |
15 | ## step2a
16 | 音声の読み込みと前処理を行います。
17 |
18 | ### load audio
19 | 音声のあるフォルダを指定すると、そのフォルダ内にある音声ファイルを自動で読み込みます。
20 | 例えば`C:Users\hoge\voices`を指定した場合、`C:Users\hoge\voices\voice.mp3`は読み込まれますが、`C:Users\hoge\voices\dir\voice.mp3`は読み込まれません。
21 |
22 | 音声の読み込みには内部でffmpegを利用しているので、ffmpegで対応している拡張子であれば自動的に読み込まれます。
23 | ffmpegでint16に変換した後、float32に変換し、-1 ~ 1の間に正規化されます。
24 |
25 | ### denoising
26 | 音声についてscipyのfiltfiltによる平滑化を行います。
27 |
28 | ### 音声の分割
29 | 入力した音声はまず、一定期間(max_sil_kept=5秒?)より長く無音が続く部分を検知して音声を分割します。無音で音声を分割した後は、0.3秒のoverlapを含む4秒ごとに音声を分割します。4秒以内に区切られた音声は、音量の正規化を行った後wavファイルを`/logs/実験名/0_gt_wavs`に、そこから16kのサンプリングレートに変換して`/logs/実験名/1_16k_wavs`にwavファイルで保存します。
30 |
31 | ## step2b
32 | ### ピッチの抽出
33 | wavファイルからピッチ(音の高低)の情報を抽出します。parselmouthやpyworldに内蔵されている手法でピッチ情報(=f0)を抽出し、`/logs/実験名/2a_f0`に保存します。その後、ピッチ情報を対数で変換して1~255の整数に変換し、`/logs/実験名/2b-f0nsf`に保存します。
34 |
35 | ### feature_printの抽出
36 | HuBERTを用いてwavファイルを事前にembeddingに変換します。`/logs/実験名/1_16k_wavs`に保存したwavファイルを読み込み、HuBERTでwavファイルを256次元の特徴量に変換し、npy形式で`/logs/実験名/3_feature256`に保存します。
37 |
38 | ## step3
39 | モデルのトレーニングを行います。
40 | ### 初心者向け用語解説
41 | 深層学習ではデータセットを分割し、少しずつ学習を進めていきます。一回のモデルの更新(step)では、batch_size個のデータを取り出し予測と誤差の修正を行います。これをデータセットに対して一通り行うと一epochと数えます。
42 |
43 | そのため、学習時間は 1step当たりの学習時間 x (データセット内のデータ数 ÷ バッチサイズ) x epoch数 かかります。一般にバッチサイズを大きくするほど学習は安定し、(1step当たりの学習時間÷バッチサイズ)は小さくなりますが、その分GPUのメモリを多く使用します。GPUのRAMはnvidia-smiコマンド等で確認できます。実行環境のマシンに合わせてバッチサイズをできるだけ大きくするとより短時間で学習が可能です。
44 |
45 | ### pretrained modelの指定
46 | RVCではモデルの訓練を0からではなく、事前学習済みの重みから開始するため、少ないデータセットで学習を行えます。
47 |
48 | デフォルトでは
49 |
50 | - 音高ガイドを考慮する場合、`RVCのある場所/pretrained/f0G40k.pth`と`RVCのある場所/pretrained/f0D40k.pth`を読み込みます。
51 | - 音高ガイドを考慮しない場合、`RVCのある場所/pretrained/G40k.pth`と`RVCのある場所/pretrained/D40k.pth`を読み込みます。
52 |
53 | 学習時はsave_every_epochごとにモデルのパラメータが`logs/実験名/G_{}.pth`と`logs/実験名/D_{}.pth`に保存されますが、このパスを指定することで学習を再開したり、もしくは違う実験で学習したモデルの重みから学習を開始できます。
54 |
55 | ### indexの学習
56 | RVCでは学習時に使われたHuBERTの特徴量を保存し、推論時は学習時の特徴量から近い特徴量を探してきて推論を行います。この検索を高速に行うために事前にindexの学習を行います。
57 | indexの学習には近似近傍探索ライブラリのfaissを用います。`/logs/実験名/3_feature256`の特徴量を読み込み、それを用いて学習したindexを`/logs/実験名/add_XXX.index`として保存します。
58 | (20230428updateよりtotal_fea.npyはindexから読み込むので不要になりました。)
59 |
60 | ### ボタンの説明
61 | - モデルのトレーニング: step2bまでを実行した後、このボタンを押すとモデルの学習を行います。
62 | - 特徴インデックスのトレーニング: モデルのトレーニング後、indexの学習を行います。
63 | - ワンクリックトレーニング: step2bまでとモデルのトレーニング、特徴インデックスのトレーニングを一括で行います。
64 |
65 |
--------------------------------------------------------------------------------
/docs/kr/README.ko.han.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # Retrieval-based-Voice-Conversion-WebUI
4 | VITS基盤의 簡單하고使用하기 쉬운音聲變換틀
5 |
6 |
7 |
8 | [](https://github.com/fumiama/Retrieval-based-Voice-Conversion-WebUI)
10 |
11 | 
12 |
13 | [](https://github.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/blob/main/LICENSE)
14 | [](https://huggingface.co/lj1995/VoiceConversionWebUI/tree/main/)
15 |
16 | [](https://discord.gg/HcsmBBGyVk)
17 |
18 |
19 |
20 | ------
21 |
22 | [**English**](../en/README.en.md) | [**中文简体**](../../README.md) | [**日本語**](../jp/README.ja.md) | [**한국어**](../kr/README.ko.md) ([**韓國語**](../kr/README.ko.han.md)) | [**Français**](../fr/README.fr.md) | [**Türkçe**](../tr/README.tr.md) | [**Português**](../pt/README.pt.md)
23 |
24 | > [示範映像](https://www.bilibili.com/video/BV1pm4y1z7Gm/)을 確認해 보세요!
25 |
26 | > RVC를活用한實時間音聲變換: [w-okada/voice-changer](https://github.com/w-okada/voice-changer)
27 |
28 | > 基本모델은 50時間假量의 高品質 오픈 소스 VCTK 데이터셋을 使用하였으므로, 著作權上의 念慮가 없으니 安心하고 使用하시기 바랍니다.
29 |
30 | > 著作權問題가 없는 高品質의 노래를 以後에도 繼續해서 訓練할 豫定입니다.
31 |
32 | ## 紹介
33 | 本Repo는 다음과 같은 特徵을 가지고 있습니다:
34 | + top1檢索을利用하여 入力音色特徵을 訓練세트音色特徵으로 代替하여 音色의漏出을 防止;
35 | + 相對的으로 낮은性能의 GPU에서도 빠른訓練可能;
36 | + 적은量의 데이터로 訓練해도 좋은 結果를 얻을 수 있음 (最小10分以上의 低雜음音聲데이터를 使用하는 것을 勸獎);
37 | + 모델融合을通한 音色의 變調可能 (ckpt處理탭->ckpt混合選擇);
38 | + 使用하기 쉬운 WebUI (웹 使用者인터페이스);
39 | + UVR5 모델을 利用하여 목소리와 背景音樂의 빠른 分離;
40 |
41 | ## 環境의準備
42 | poetry를通해 依存를設置하는 것을 勸獎합니다.
43 |
44 | 다음命令은 Python 버전3.8以上의環境에서 實行되어야 합니다:
45 | ```bash
46 | # PyTorch 關聯主要依存設置, 이미設置되어 있는 境遇 건너뛰기 可能
47 | # 參照: https://pytorch.org/get-started/locally/
48 | pip install torch torchvision torchaudio
49 |
50 | # Windows + Nvidia Ampere Architecture(RTX30xx)를 使用하고 있다面, #21 에서 명시된 것과 같이 PyTorch에 맞는 CUDA 버전을 指定해야 합니다.
51 | #pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117
52 |
53 | # Poetry 設置, 이미設置되어 있는 境遇 건너뛰기 可能
54 | # Reference: https://python-poetry.org/docs/#installation
55 | curl -sSL https://install.python-poetry.org | python3 -
56 |
57 | # 依存設置
58 | poetry install
59 | ```
60 | pip를 活用하여依存를 設置하여도 無妨합니다.
61 |
62 | ```bash
63 | pip install -r requirements/main.txt
64 | ```
65 |
66 | ## 其他預備모델準備
67 | RVC 모델은 推論과訓練을 依하여 다른 預備모델이 必要합니다.
68 |
69 | [Huggingface space](https://huggingface.co/lj1995/VoiceConversionWebUI/tree/main/)를 通해서 다운로드 할 수 있습니다.
70 |
71 | 다음은 RVC에 必要한 預備모델 및 其他 파일 目錄입니다:
72 | ```bash
73 | ./assets/hubert/hubert_base.pt
74 |
75 | ./assets/pretrained
76 |
77 | ./assets/uvr5_weights
78 |
79 | V2 버전 모델을 테스트하려면 추가 다운로드가 필요합니다.
80 |
81 | ./assets/pretrained_v2
82 |
83 | ```
84 | 그後 以下의 命令을 使用하여 WebUI를 始作할 수 있습니다:
85 | ```bash
86 | python web.py
87 | ```
88 | Windows를 使用하는境遇 `RVC-beta.7z`를 다운로드 및 壓縮解除하여 RVC를 直接使用하거나 `go-web.bat`을 使用하여 WebUi를 直接할 수 있습니다.
89 |
90 | ## 參考
91 | + [ContentVec](https://github.com/auspicious3000/contentvec/)
92 | + [VITS](https://github.com/jaywalnut310/vits)
93 | + [HIFIGAN](https://github.com/jik876/hifi-gan)
94 | + [Gradio](https://github.com/gradio-app/gradio)
95 | + [Ultimate Vocal Remover](https://github.com/Anjok07/ultimatevocalremovergui)
96 | + [audio-slicer](https://github.com/openvpi/audio-slicer)
97 | ## 모든寄與者분들의勞力에感謝드립니다
98 |
99 | [](https://github.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/graphs/contributors)
100 |
101 |
--------------------------------------------------------------------------------
/docs/kr/training_tips_ko.md:
--------------------------------------------------------------------------------
1 | RVC 훈련에 대한 설명과 팁들
2 | ======================================
3 | 본 팁에서는 어떻게 데이터 훈련이 이루어지고 있는지 설명합니다.
4 |
5 | # 훈련의 흐름
6 | GUI의 훈련 탭의 단계를 따라 설명합니다.
7 |
8 | ## step1
9 | 실험 이름을 지정합니다. 또한, 모델이 피치(소리의 높낮이)를 고려해야 하는지 여부를 여기에서 설정할 수도 있습니다..
10 | 각 실험을 위한 데이터는 `/logs/experiment name/`에 배치됩니다..
11 |
12 | ## step2a
13 | 음성 파일을 불러오고 전처리합니다.
14 |
15 | ### 음성 파일 불러오기
16 | 음성 파일이 있는 폴더를 지정하면 해당 폴더에 있는 음성 파일이 자동으로 가져와집니다.
17 | 예를 들어 `C:Users\hoge\voices`를 지정하면 `C:Users\hoge\voices\voice.mp3`가 읽히지만 `C:Users\hoge\voices\dir\voice.mp3`는 읽히지 않습니다.
18 |
19 | 음성 로드에는 내부적으로 ffmpeg를 이용하고 있으므로, ffmpeg로 대응하고 있는 확장자라면 자동적으로 읽힙니다.
20 | ffmpeg에서 int16으로 변환한 후 float32로 변환하고 -1과 1 사이에 정규화됩니다.
21 |
22 | ### 잡음 제거
23 | 음성 파일에 대해 scipy의 filtfilt를 이용하여 잡음을 처리합니다.
24 |
25 | ### 음성 분할
26 | 입력한 음성 파일은 먼저 일정 기간(max_sil_kept=5초?)보다 길게 무음이 지속되는 부분을 감지하여 음성을 분할합니다.무음으로 음성을 분할한 후에는 0.3초의 overlap을 포함하여 4초마다 음성을 분할합니다.4초 이내에 구분된 음성은 음량의 정규화를 실시한 후 wav 파일을 `/logs/실험명/0_gt_wavs`로, 거기에서 16k의 샘플링 레이트로 변환해 `/logs/실험명/1_16k_wavs`에 wav 파일로 저장합니다.
27 |
28 | ## step2b
29 | ### 피치 추출
30 | wav 파일에서 피치(소리의 높낮이) 정보를 추출합니다. parselmouth나 pyworld에 내장되어 있는 메서드으로 피치 정보(=f0)를 추출해, `/logs/실험명/2a_f0`에 저장합니다. 그 후 피치 정보를 로그로 변환하여 1~255 정수로 변환하고 `/logs/실험명/2b-f0nsf`에 저장합니다.
31 |
32 | ### feature_print 추출
33 | HuBERT를 이용하여 wav 파일을 미리 embedding으로 변환합니다. `/logs/실험명/1_16k_wavs`에 저장한 wav 파일을 읽고 HuBERT에서 wav 파일을 256차원 feature들로 변환한 후 npy 형식으로 `/logs/실험명/3_feature256`에 저장합니다.
34 |
35 | ## step3
36 | 모델의 훈련을 진행합니다.
37 |
38 | ### 초보자용 용어 해설
39 | 심층학습(딥러닝)에서는 데이터셋을 분할하여 조금씩 학습을 진행합니다.한 번의 모델 업데이트(step) 단계 당 batch_size개의 데이터를 탐색하여 예측과 오차를 수정합니다. 데이터셋 전부에 대해 이 작업을 한 번 수행하는 이를 하나의 epoch라고 계산합니다.
40 |
41 | 따라서 학습 시간은 단계당 학습 시간 x (데이터셋 내 데이터의 수 / batch size) x epoch 수가 소요됩니다. 일반적으로 batch size가 클수록 학습이 안정적이게 됩니다. (step당 학습 시간 ÷ batch size)는 작아지지만 GPU 메모리를 더 많이 사용합니다. GPU RAM은 nvidia-smi 명령어를 통해 확인할 수 있습니다. 실행 환경에 따라 배치 크기를 최대한 늘리면 짧은 시간 내에 학습이 가능합니다.
42 |
43 | ### 사전 학습된 모델 지정
44 | RVC는 적은 데이터셋으로도 훈련이 가능하도록 사전 훈련된 가중치에서 모델 훈련을 시작합니다. 기본적으로 `rvc-location/pretrained/f0G40k.pth` 및 `rvc-location/pretrained/f0D40k.pth`를 불러옵니다. 학습을 할 시에, 모델 파라미터는 각 save_every_epoch별로 `logs/experiment name/G_{}.pth` 와 `logs/experiment name/D_{}.pth`로 저장이 되는데, 이 경로를 지정함으로써 학습을 재개하거나, 다른 실험에서 학습한 모델의 가중치에서 학습을 시작할 수 있습니다.
45 |
46 | ### index의 학습
47 | RVC에서는 학습시에 사용된 HuBERT의 feature값을 저장하고, 추론 시에는 학습 시 사용한 feature값과 유사한 feature 값을 탐색해 추론을 진행합니다. 이 탐색을 고속으로 수행하기 위해 사전에 index을 학습하게 됩니다.
48 | Index 학습에는 근사 근접 탐색법 라이브러리인 Faiss를 사용하게 됩니다. `/logs/실험명/3_feature256`의 feature값을 불러와, 이를 모두 결합시킨 feature값을 `/logs/실험명/total_fea.npy`로서 저장, 그것을 사용해 학습한 index를`/logs/실험명/add_XXX.index`로 저장합니다.
49 |
50 | ### 버튼 설명
51 | - モデルのトレーニング (모델 학습): step2b까지 실행한 후, 이 버튼을 눌러 모델을 학습합니다.
52 | - 特徴インデックスのトレーニング (특징 지수 훈련): 모델의 훈련 후, index를 학습합니다.
53 | - ワンクリックトレーニング (원클릭 트레이닝): step2b까지의 모델 훈련, feature index 훈련을 일괄로 실시합니다.
--------------------------------------------------------------------------------
/docs/pt/training_tips_pt.md:
--------------------------------------------------------------------------------
1 | Instruções e dicas para treinamento RVC
2 | ======================================
3 | Estas DICAS explicam como o treinamento de dados é feito.
4 |
5 | # Fluxo de treinamento
6 | Explicarei ao longo das etapas na guia de treinamento da GUI.
7 |
8 | ## Passo 1
9 | Defina o nome do experimento aqui.
10 |
11 | Você também pode definir aqui se o modelo deve levar em consideração o pitch.
12 | Se o modelo não considerar o tom, o modelo será mais leve, mas não será adequado para cantar.
13 |
14 | Os dados de cada experimento são colocados em `/logs/nome-do-seu-modelo/`.
15 |
16 | ## Passo 2a
17 | Carrega e pré-processa áudio.
18 |
19 | ### Carregar áudio
20 | Se você especificar uma pasta com áudio, os arquivos de áudio dessa pasta serão lidos automaticamente.
21 | Por exemplo, se você especificar `C:Users\hoge\voices`, `C:Users\hoge\voices\voice.mp3` será carregado, mas `C:Users\hoge\voices\dir\voice.mp3` será Não carregado.
22 |
23 | Como o ffmpeg é usado internamente para leitura de áudio, se a extensão for suportada pelo ffmpeg, ela será lida automaticamente.
24 | Após converter para int16 com ffmpeg, converta para float32 e normalize entre -1 e 1.
25 |
26 | ### Eliminar ruído
27 | O áudio é suavizado pelo filtfilt do scipy.
28 |
29 | ### Divisão de áudio
30 | Primeiro, o áudio de entrada é dividido pela detecção de partes de silêncio que duram mais que um determinado período (max_sil_kept=5 segundos?). Após dividir o áudio no silêncio, divida o áudio a cada 4 segundos com uma sobreposição de 0,3 segundos. Para áudio separado em 4 segundos, após normalizar o volume, converta o arquivo wav para `/logs/nome-do-seu-modelo/0_gt_wavs` e, em seguida, converta-o para taxa de amostragem de 16k para `/logs/nome-do-seu-modelo/1_16k_wavs ` como um arquivo wav.
31 |
32 | ## Passo 2b
33 | ### Extrair pitch
34 | Extraia informações de pitch de arquivos wav. Extraia as informações de pitch (=f0) usando o método incorporado em Parselmouth ou pyworld e salve-as em `/logs/nome-do-seu-modelo/2a_f0`. Em seguida, converta logaritmicamente as informações de pitch para um número inteiro entre 1 e 255 e salve-as em `/logs/nome-do-seu-modelo/2b-f0nsf`.
35 |
36 | ### Extrair feature_print
37 | Converta o arquivo wav para incorporação antecipadamente usando HuBERT. Leia o arquivo wav salvo em `/logs/nome-do-seu-modelo/1_16k_wavs`, converta o arquivo wav em recursos de 256 dimensões com HuBERT e salve no formato npy em `/logs/nome-do-seu-modelo/3_feature256`.
38 |
39 | ## Passo 3
40 | treinar o modelo.
41 | ### Glossário para iniciantes
42 | No aprendizado profundo, o conjunto de dados é dividido e o aprendizado avança aos poucos. Em uma atualização do modelo (etapa), os dados batch_size são recuperados e previsões e correções de erros são realizadas. Fazer isso uma vez para um conjunto de dados conta como um epoch.
43 |
44 | Portanto, o tempo de aprendizagem é o tempo de aprendizagem por etapa x (o número de dados no conjunto de dados/tamanho do lote) x o número de epoch. Em geral, quanto maior o tamanho do lote, mais estável se torna o aprendizado (tempo de aprendizado por etapa ÷ tamanho do lote) fica menor, mas usa mais memória GPU. A RAM da GPU pode ser verificada com o comando nvidia-smi. O aprendizado pode ser feito em pouco tempo aumentando o tamanho do lote tanto quanto possível de acordo com a máquina do ambiente de execução.
45 |
46 | ### Especifique o modelo pré-treinado
47 | O RVC começa a treinar o modelo a partir de pesos pré-treinados em vez de 0, para que possa ser treinado com um pequeno conjunto de dados.
48 |
49 | Por padrão
50 |
51 | - Se você considerar o pitch, ele carrega `rvc-location/pretrained/f0G40k.pth` e `rvc-location/pretrained/f0D40k.pth`.
52 | - Se você não considerar o pitch, ele carrega `rvc-location/pretrained/f0G40k.pth` e `rvc-location/pretrained/f0D40k.pth`.
53 |
54 | Ao aprender, os parâmetros do modelo são salvos em `logs/nome-do-seu-modelo/G_{}.pth` e `logs/nome-do-seu-modelo/D_{}.pth` para cada save_every_epoch, mas especificando nesse caminho, você pode começar a aprender. Você pode reiniciar ou iniciar o treinamento a partir de weights de modelo aprendidos em um experimento diferente.
55 |
56 | ### Index de aprendizado
57 | O RVC salva os valores de recursos do HuBERT usados durante o treinamento e, durante a inferência, procura valores de recursos que sejam semelhantes aos valores de recursos usados durante o aprendizado para realizar a inferência. Para realizar esta busca em alta velocidade, o index é aprendido previamente.
58 | Para aprendizagem de index, usamos a biblioteca de pesquisa de associação de áreas aproximadas faiss. Leia o valor do recurso `logs/nome-do-seu-modelo/3_feature256` e use-o para aprender o index, e salve-o como `logs/nome-do-seu-modelo/add_XXX.index`.
59 |
60 | (A partir da versão 20230428update, ele é lido do index e não é mais necessário salvar/especificar.)
61 |
62 | ### Descrição do botão
63 | - Treinar modelo: Após executar o passo 2b, pressione este botão para treinar o modelo.
64 | - Treinar índice de recursos: após treinar o modelo, execute o aprendizado do index.
65 | - Treinamento com um clique: etapa 2b, treinamento de modelo e treinamento de index de recursos, tudo de uma vez.
--------------------------------------------------------------------------------
/docs/tr/training_tips_tr.md:
--------------------------------------------------------------------------------
1 | ## RVC Eğitimi için Talimatlar ve İpuçları
2 | ======================================
3 | Bu TALİMAT, veri eğitiminin nasıl yapıldığını açıklamaktadır.
4 |
5 | # Eğitim Akışı
6 | Eğitim sekmesindeki adımları takip ederek açıklayacağım.
7 |
8 | ## Adım 1
9 | Deney adını burada belirleyin.
10 |
11 | Ayrıca burada modelin pitch'i dikkate alıp almayacağını da belirleyebilirsiniz.
12 | Eğer model pitch'i dikkate almazsa, model daha hafif olacak, ancak şarkı söyleme için uygun olmayacaktır.
13 |
14 | Her deney için veriler `/logs/your-experiment-name/` dizinine yerleştirilir.
15 |
16 | ## Adım 2a
17 | Ses yüklenir ve ön işleme yapılır.
18 |
19 | ### Ses Yükleme
20 | Ses içeren bir klasör belirtirseniz, bu klasördeki ses dosyaları otomatik olarak okunur.
21 | Örneğin, `C:Users\hoge\voices` belirtirseniz, `C:Users\hoge\voices\voice.mp3` yüklenecek, ancak `C:Users\hoge\voices\dir\voice.mp3` yüklenmeyecektir.
22 |
23 | ### Gürültü Temizleme
24 | Ses scipy'nin filtfilt işlevi ile yumuşatılır.
25 |
26 | ### Ses Ayırma
27 | İlk olarak, giriş sesi belirli bir süreden (max_sil_kept=5 saniye?) daha uzun süren sessiz kısımları tespit ederek böler. Sessizlik üzerinde ses bölündükten sonra sesi 4 saniyede bir 0.3 saniyelik bir örtüşme ile böler. 4 saniye içinde ayrılan sesler için ses normalleştirildikten sonra wav dosyası olarak `/logs/your-experiment-name/0_gt_wavs`'a, ardından 16 kHz örnekleme hızına dönüştürülerek `/logs/your-experiment-name/1_16k_wavs` olarak kaydedilir.
28 |
29 | ## Adım 2b
30 | ### Pitch Çıkarımı
31 | Wav dosyalarından pitch bilgisi çıkarılır. ParSelMouth veya PyWorld'e dahili olarak yerleştirilmiş yöntemi kullanarak pitch bilgisi (=f0) çıkarılır ve `/logs/your-experiment-name/2a_f0` dizinine kaydedilir. Ardından pitch bilgisi logaritmik olarak 1 ile 255 arasında bir tamsayıya dönüştürülüp `/logs/your-experiment-name/2b-f0nsf` dizinine kaydedilir.
32 |
33 | ### Özellik Çıkarımı
34 | HuBERT'i kullanarak önceden gömme olarak wav dosyasını çıkarır. `/logs/your-experiment-name/1_16k_wavs`'a kaydedilen wav dosyasını okuyarak, wav dosyasını 256 boyutlu HuBERT özelliklerine dönüştürür ve npy formatında `/logs/your-experiment-name/3_feature256` dizinine kaydeder.
35 |
36 | ## Adım 3
37 | Modeli eğit.
38 | ### Başlangıç Seviyesi Sözlüğü
39 | Derin öğrenmede, veri kümesi bölmeye ve öğrenmeye adım adım devam eder. Bir model güncellemesinde (adım), batch_size veri alınır ve tahminler ve hata düzeltmeleri yapılır. Bunun bir defa bir veri kümesi için yapılması bir dönem olarak sayılır.
40 |
41 | Bu nedenle, öğrenme zamanı adım başına öğrenme zamanı x (veri kümesindeki veri sayısı / batch boyutu) x dönem sayısıdır. Genel olarak, batch boyutu ne kadar büyükse, öğrenme daha istikrarlı hale gelir (adım başına öğrenme süresi ÷ batch boyutu) küçülür, ancak daha fazla GPU belleği kullanır. GPU RAM'ı nvidia-smi komutu ile kontrol edilebilir. Çalışma ortamının makinesine göre batch boyutunu mümkün olduğunca artırarak öğrenme süresini kısa sürede yapabilirsiniz.
42 |
43 | ### Önceden Eğitilmiş Modeli Belirtme
44 | RVC, modeli 0'dan değil önceden eğitilmiş ağırlıklardan başlatarak eğitir, bu nedenle küçük bir veri kümesi ile eğitilebilir.
45 |
46 | Varsayılan olarak
47 |
48 | - Eğer pitch'i dikkate alıyorsanız, `rvc-location/pretrained/f0G40k.pth` ve `rvc-location/pretrained/f0D40k.pth` yüklenir.
49 | - Eğer pitch'i dikkate almıyorsanız, yine `rvc-location/pretrained/f0G40k.pth` ve `rvc-location/pretrained/f0D40k.pth` yüklenir.
50 |
51 | Öğrenirken model parametreleri her save_every_epoch için `logs/your-experiment-name/G_{}.pth` ve `logs/your-experiment-name/D_{}.pth` olarak kaydedilir, ancak bu yolu belirterek öğrenmeye başlayabilirsiniz. Farklı bir deneyde öğrenilen model ağırlıklarından öğrenmeye yeniden başlayabilir veya eğitimi başlatabilirsiniz.
52 |
53 | ### Öğrenme İndeksi
54 | RVC, eğitim sırasında kullanılan HuBERT özellik değerlerini kaydeder ve çıkarım sırasında, öğrenme sırasında kullanılan özellik değerlerine benzer özellik değerlerini arayarak çıkarım yapar. Bu aramayı yüksek hızda gerçekleştirebilmek için indeks öğrenilir.
55 | İndeks öğrenimi için yaklaş
56 |
57 | ık komşuluk arama kütüphanesi faiss kullanılır. `/logs/your-experiment-name/3_feature256`'daki özellik değerini okur ve indeksi öğrenmek için kullanır, `logs/your-experiment-name/add_XXX.index` olarak kaydedilir.
58 |
59 | (20230428 güncelleme sürümünden itibaren indeks okunur ve kaydetmek/belirtmek artık gerekli değildir.)
60 |
61 | ### Düğme Açıklaması
62 | - Modeli Eğit: Adım 2b'yi çalıştırdıktan sonra, modeli eğitmek için bu düğmeye basın.
63 | - Özellik İndeksini Eğit: Modeli eğittikten sonra, indeks öğrenme işlemi yapın.
64 | - Tek Tıklamayla Eğitim: Adım 2b, model eğitimi ve özellik indeks eğitimini bir arada yapar.
65 |
--------------------------------------------------------------------------------
/i18n/i18n.py:
--------------------------------------------------------------------------------
1 | import json
2 | import locale
3 | import os
4 | from configs import singleton_variable
5 |
6 |
7 | def load_language_list(language):
8 | with open(f"./i18n/locale/{language}.json", "r", encoding="utf-8") as f:
9 | language_list = json.load(f)
10 | return language_list
11 |
12 |
13 | @singleton_variable
14 | class I18nAuto:
15 | def __init__(self, language=None):
16 | if language in ["Auto", None]:
17 | language = locale.getdefaultlocale(
18 | envvars=("LANG", "LC_ALL", "LC_CTYPE", "LANGUAGE")
19 | )[0]
20 | if not os.path.exists(f"./i18n/locale/{language}.json"):
21 | language = "en_US"
22 | self.language = language
23 | self.language_map = load_language_list(language)
24 |
25 | def __call__(self, key):
26 | return self.language_map.get(key, key)
27 |
28 | def __repr__(self):
29 | return "Language: " + self.language
30 |
--------------------------------------------------------------------------------
/i18n/locale_diff.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | from collections import OrderedDict
4 |
5 | # Define the standard file name
6 | standard_file = "locale/en_US.json"
7 |
8 | # Find all JSON files in the directory
9 | dir_path = "locale/"
10 | languages = [
11 | os.path.join(dir_path, f)
12 | for f in os.listdir(dir_path)
13 | if f.endswith(".json") and f != standard_file
14 | ]
15 |
16 | # Load the standard file
17 | with open(standard_file, "r", encoding="utf-8") as f:
18 | standard_data = json.load(f, object_pairs_hook=OrderedDict)
19 |
20 | # Loop through each language file
21 | for lang_file in languages:
22 | # Load the language file
23 | with open(lang_file, "r", encoding="utf-8") as f:
24 | lang_data = json.load(f, object_pairs_hook=OrderedDict)
25 |
26 | # Find the difference between the language file and the standard file
27 | diff = set(standard_data.keys()) - set(lang_data.keys())
28 |
29 | miss = set(lang_data.keys()) - set(standard_data.keys())
30 |
31 | # Add any missing keys to the language file
32 | for key in diff:
33 | lang_data[key] = key
34 |
35 | # Del any extra keys to the language file
36 | for key in miss:
37 | del lang_data[key]
38 |
39 | # Sort the keys of the language file to match the order of the standard file
40 | lang_data = OrderedDict(
41 | sorted(lang_data.items(), key=lambda x: list(standard_data.keys()).index(x[0]))
42 | )
43 |
44 | # Save the updated language file
45 | with open(lang_file, "w", encoding="utf-8") as f:
46 | json.dump(lang_data, f, ensure_ascii=False, indent=4, sort_keys=True)
47 | f.write("\n")
48 |
--------------------------------------------------------------------------------
/i18n/scan_i18n.py:
--------------------------------------------------------------------------------
1 | import ast
2 | import glob
3 | import json
4 | from collections import OrderedDict
5 |
6 |
7 | def extract_i18n_strings(node):
8 | i18n_strings = []
9 |
10 | if (
11 | isinstance(node, ast.Call)
12 | and isinstance(node.func, ast.Name)
13 | and node.func.id == "i18n"
14 | ):
15 | for arg in node.args:
16 | if isinstance(arg, ast.Str):
17 | i18n_strings.append(arg.s)
18 |
19 | for child_node in ast.iter_child_nodes(node):
20 | i18n_strings.extend(extract_i18n_strings(child_node))
21 |
22 | return i18n_strings
23 |
24 |
25 | # scan the directory for all .py files (recursively)
26 | # for each file, parse the code into an AST
27 | # for each AST, extract the i18n strings
28 |
29 | strings = []
30 | for filename in glob.iglob("**/*.py", recursive=True):
31 | with open(filename, "r") as f:
32 | code = f.read()
33 | if "I18nAuto" in code:
34 | tree = ast.parse(code)
35 | i18n_strings = extract_i18n_strings(tree)
36 | print(filename, len(i18n_strings))
37 | strings.extend(i18n_strings)
38 | code_keys = set(strings)
39 | print()
40 | print("Total unique:", len(code_keys))
41 |
42 |
43 | standard_file = "i18n/locale/en_US.json"
44 | with open(standard_file, "r", encoding="utf-8") as f:
45 | standard_data = json.load(f, object_pairs_hook=OrderedDict)
46 | standard_keys = set(standard_data.keys())
47 |
48 | # Define the standard file name
49 | unused_keys = standard_keys - code_keys
50 | print("Unused keys:", len(unused_keys))
51 | for unused_key in unused_keys:
52 | print("\t", unused_key)
53 |
54 | missing_keys = code_keys - standard_keys
55 | print("Missing keys:", len(missing_keys))
56 | for missing_key in missing_keys:
57 | print("\t", missing_key)
58 |
59 | code_keys_dict = OrderedDict()
60 | for s in strings:
61 | code_keys_dict[s] = s
62 |
63 | # write back
64 | with open(standard_file, "w", encoding="utf-8") as f:
65 | json.dump(code_keys_dict, f, ensure_ascii=False, indent=4, sort_keys=True)
66 | f.write("\n")
67 |
--------------------------------------------------------------------------------
/infer/lib/train/losses.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 |
4 | def feature_loss(fmap_r, fmap_g):
5 | loss = 0
6 | for dr, dg in zip(fmap_r, fmap_g):
7 | for rl, gl in zip(dr, dg):
8 | rl = rl.float().detach()
9 | gl = gl.float()
10 | loss += torch.mean(torch.abs(rl - gl))
11 |
12 | return loss * 2
13 |
14 |
15 | def discriminator_loss(disc_real_outputs, disc_generated_outputs):
16 | loss = 0
17 | r_losses = []
18 | g_losses = []
19 | for dr, dg in zip(disc_real_outputs, disc_generated_outputs):
20 | dr = dr.float()
21 | dg = dg.float()
22 | r_loss = torch.mean((1 - dr) ** 2)
23 | g_loss = torch.mean(dg**2)
24 | loss += r_loss + g_loss
25 | r_losses.append(r_loss.item())
26 | g_losses.append(g_loss.item())
27 |
28 | return loss, r_losses, g_losses
29 |
30 |
31 | def generator_loss(disc_outputs):
32 | loss = 0
33 | gen_losses = []
34 | for dg in disc_outputs:
35 | dg = dg.float()
36 | l = torch.mean((1 - dg) ** 2)
37 | gen_losses.append(l)
38 | loss += l
39 |
40 | return loss, gen_losses
41 |
42 |
43 | def kl_loss(z_p, logs_q, m_p, logs_p, z_mask):
44 | """
45 | z_p, logs_q: [b, h, t_t]
46 | m_p, logs_p: [b, h, t_t]
47 | """
48 | z_p = z_p.float()
49 | logs_q = logs_q.float()
50 | m_p = m_p.float()
51 | logs_p = logs_p.float()
52 | z_mask = z_mask.float()
53 |
54 | kl = logs_p - logs_q - 0.5
55 | kl += 0.5 * ((z_p - m_p) ** 2) * torch.exp(-2.0 * logs_p)
56 | kl = torch.sum(kl * z_mask)
57 | l = kl / torch.sum(z_mask)
58 | return l
59 |
--------------------------------------------------------------------------------
/infer/lib/train/mel_processing.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.utils.data
3 | from librosa.filters import mel as librosa_mel_fn
4 | import logging
5 |
6 | logger = logging.getLogger(__name__)
7 |
8 | MAX_WAV_VALUE = 32768.0
9 |
10 |
11 | def dynamic_range_compression_torch(x, C=1, clip_val=1e-5):
12 | """
13 | PARAMS
14 | ------
15 | C: compression factor
16 | """
17 | return torch.log(torch.clamp(x, min=clip_val) * C)
18 |
19 |
20 | def dynamic_range_decompression_torch(x, C=1):
21 | """
22 | PARAMS
23 | ------
24 | C: compression factor used to compress
25 | """
26 | return torch.exp(x) / C
27 |
28 |
29 | def spectral_normalize_torch(magnitudes):
30 | return dynamic_range_compression_torch(magnitudes)
31 |
32 |
33 | def spectral_de_normalize_torch(magnitudes):
34 | return dynamic_range_decompression_torch(magnitudes)
35 |
36 |
37 | # Reusable banks
38 | mel_basis = {}
39 | hann_window = {}
40 |
41 |
42 | def spectrogram_torch(y, n_fft, sampling_rate, hop_size, win_size, center=False):
43 | """Convert waveform into Linear-frequency Linear-amplitude spectrogram.
44 |
45 | Args:
46 | y :: (B, T) - Audio waveforms
47 | n_fft
48 | sampling_rate
49 | hop_size
50 | win_size
51 | center
52 | Returns:
53 | :: (B, Freq, Frame) - Linear-frequency Linear-amplitude spectrogram
54 | """
55 |
56 | # Window - Cache if needed
57 | global hann_window
58 | dtype_device = str(y.dtype) + "_" + str(y.device)
59 | wnsize_dtype_device = str(win_size) + "_" + dtype_device
60 | if wnsize_dtype_device not in hann_window:
61 | hann_window[wnsize_dtype_device] = torch.hann_window(win_size).to(
62 | dtype=y.dtype, device=y.device
63 | )
64 |
65 | # Padding
66 | y = torch.nn.functional.pad(
67 | y.unsqueeze(1),
68 | (int((n_fft - hop_size) / 2), int((n_fft - hop_size) / 2)),
69 | mode="reflect",
70 | )
71 | y = y.squeeze(1)
72 |
73 | # Complex Spectrogram :: (B, T) -> (B, Freq, Frame, RealComplex=2)
74 | spec = torch.stft(
75 | y,
76 | n_fft,
77 | hop_length=hop_size,
78 | win_length=win_size,
79 | window=hann_window[wnsize_dtype_device],
80 | center=center,
81 | pad_mode="reflect",
82 | normalized=False,
83 | onesided=True,
84 | return_complex=True,
85 | )
86 |
87 | # Linear-frequency Linear-amplitude spectrogram :: (B, Freq, Frame, RealComplex=2) -> (B, Freq, Frame)
88 | spec = torch.sqrt(spec.real.pow(2) + spec.imag.pow(2) + 1e-6)
89 | return spec
90 |
91 |
92 | def spec_to_mel_torch(spec, n_fft, num_mels, sampling_rate, fmin, fmax):
93 | # MelBasis - Cache if needed
94 | global mel_basis
95 | dtype_device = str(spec.dtype) + "_" + str(spec.device)
96 | fmax_dtype_device = str(fmax) + "_" + dtype_device
97 | if fmax_dtype_device not in mel_basis:
98 | mel = librosa_mel_fn(
99 | sr=sampling_rate, n_fft=n_fft, n_mels=num_mels, fmin=fmin, fmax=fmax
100 | )
101 | mel_basis[fmax_dtype_device] = torch.from_numpy(mel).to(
102 | dtype=spec.dtype, device=spec.device
103 | )
104 |
105 | # Mel-frequency Log-amplitude spectrogram :: (B, Freq=num_mels, Frame)
106 | melspec = torch.matmul(mel_basis[fmax_dtype_device], spec)
107 | melspec = spectral_normalize_torch(melspec)
108 | return melspec
109 |
110 |
111 | def mel_spectrogram_torch(
112 | y, n_fft, num_mels, sampling_rate, hop_size, win_size, fmin, fmax, center=False
113 | ):
114 | """Convert waveform into Mel-frequency Log-amplitude spectrogram.
115 |
116 | Args:
117 | y :: (B, T) - Waveforms
118 | Returns:
119 | melspec :: (B, Freq, Frame) - Mel-frequency Log-amplitude spectrogram
120 | """
121 | # Linear-frequency Linear-amplitude spectrogram :: (B, T) -> (B, Freq, Frame)
122 | spec = spectrogram_torch(y, n_fft, sampling_rate, hop_size, win_size, center)
123 |
124 | # Mel-frequency Log-amplitude spectrogram :: (B, Freq, Frame) -> (B, Freq=num_mels, Frame)
125 | melspec = spec_to_mel_torch(spec, n_fft, num_mels, sampling_rate, fmin, fmax)
126 |
127 | return melspec
128 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/layers.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import spec_utils
6 |
7 |
8 | class Conv2DBNActiv(nn.Module):
9 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
10 | super(Conv2DBNActiv, self).__init__()
11 | self.conv = nn.Sequential(
12 | nn.Conv2d(
13 | nin,
14 | nout,
15 | kernel_size=ksize,
16 | stride=stride,
17 | padding=pad,
18 | dilation=dilation,
19 | bias=False,
20 | ),
21 | nn.BatchNorm2d(nout),
22 | activ(),
23 | )
24 |
25 | @torch.inference_mode()
26 | def forward(self, x):
27 | return self.conv(x)
28 |
29 |
30 | class Encoder(nn.Module):
31 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.LeakyReLU):
32 | super(Encoder, self).__init__()
33 | self.conv1 = Conv2DBNActiv(nin, nout, ksize, stride, pad, activ=activ)
34 | self.conv2 = Conv2DBNActiv(nout, nout, ksize, 1, pad, activ=activ)
35 |
36 | @torch.inference_mode()
37 | def forward(self, x):
38 | h = self.conv1(x)
39 | h = self.conv2(h)
40 |
41 | return h
42 |
43 |
44 | class Decoder(nn.Module):
45 | def __init__(
46 | self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.ReLU, dropout=False
47 | ):
48 | super(Decoder, self).__init__()
49 | self.conv1 = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
50 | # self.conv2 = Conv2DBNActiv(nout, nout, ksize, 1, pad, activ=activ)
51 | self.dropout = nn.Dropout2d(0.1) if dropout else None
52 |
53 | @torch.inference_mode()
54 | def forward(self, x, skip=None):
55 | x = F.interpolate(x, scale_factor=2, mode="bilinear", align_corners=True)
56 |
57 | if skip is not None:
58 | skip = spec_utils.crop_center(skip, x)
59 | x = torch.cat([x, skip], dim=1)
60 |
61 | h = self.conv1(x)
62 | # h = self.conv2(h)
63 |
64 | if self.dropout is not None:
65 | h = self.dropout(h)
66 |
67 | return h
68 |
69 |
70 | class ASPPModule(nn.Module):
71 | def __init__(self, nin, nout, dilations=(4, 8, 12), activ=nn.ReLU, dropout=False):
72 | super(ASPPModule, self).__init__()
73 | self.conv1 = nn.Sequential(
74 | nn.AdaptiveAvgPool2d((1, None)),
75 | Conv2DBNActiv(nin, nout, 1, 1, 0, activ=activ),
76 | )
77 | self.conv2 = Conv2DBNActiv(nin, nout, 1, 1, 0, activ=activ)
78 | self.conv3 = Conv2DBNActiv(
79 | nin, nout, 3, 1, dilations[0], dilations[0], activ=activ
80 | )
81 | self.conv4 = Conv2DBNActiv(
82 | nin, nout, 3, 1, dilations[1], dilations[1], activ=activ
83 | )
84 | self.conv5 = Conv2DBNActiv(
85 | nin, nout, 3, 1, dilations[2], dilations[2], activ=activ
86 | )
87 | self.bottleneck = Conv2DBNActiv(nout * 5, nout, 1, 1, 0, activ=activ)
88 | self.dropout = nn.Dropout2d(0.1) if dropout else None
89 |
90 | @torch.inference_mode()
91 | def forward(self, x):
92 | _, _, h, w = x.size()
93 | feat1 = F.interpolate(
94 | self.conv1(x), size=(h, w), mode="bilinear", align_corners=True
95 | )
96 | feat2 = self.conv2(x)
97 | feat3 = self.conv3(x)
98 | feat4 = self.conv4(x)
99 | feat5 = self.conv5(x)
100 | out = torch.cat((feat1, feat2, feat3, feat4, feat5), dim=1)
101 | out = self.bottleneck(out)
102 |
103 | if self.dropout is not None:
104 | out = self.dropout(out)
105 |
106 | return out
107 |
108 |
109 | class LSTMModule(nn.Module):
110 | def __init__(self, nin_conv, nin_lstm, nout_lstm):
111 | super(LSTMModule, self).__init__()
112 | self.conv = Conv2DBNActiv(nin_conv, 1, 1, 1, 0)
113 | self.lstm = nn.LSTM(
114 | input_size=nin_lstm, hidden_size=nout_lstm // 2, bidirectional=True
115 | )
116 | self.dense = nn.Sequential(
117 | nn.Linear(nout_lstm, nin_lstm), nn.BatchNorm1d(nin_lstm), nn.ReLU()
118 | )
119 |
120 | @torch.inference_mode()
121 | def forward(self, x):
122 | N, _, nbins, nframes = x.size()
123 | h = self.conv(x)[:, 0] # N, nbins, nframes
124 | h = h.permute(2, 0, 1) # nframes, N, nbins
125 | h, _ = self.lstm(h)
126 | h = self.dense(h.reshape(-1, h.size()[-1])) # nframes * N, nbins
127 | h = h.reshape(nframes, N, 1, nbins)
128 | h = h.permute(1, 2, 3, 0)
129 |
130 | return h
131 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/layers_123821KB.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import spec_utils
6 |
7 |
8 | class Conv2DBNActiv(nn.Module):
9 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
10 | super(Conv2DBNActiv, self).__init__()
11 | self.conv = nn.Sequential(
12 | nn.Conv2d(
13 | nin,
14 | nout,
15 | kernel_size=ksize,
16 | stride=stride,
17 | padding=pad,
18 | dilation=dilation,
19 | bias=False,
20 | ),
21 | nn.BatchNorm2d(nout),
22 | activ(),
23 | )
24 |
25 | def __call__(self, x):
26 | return self.conv(x)
27 |
28 |
29 | class SeperableConv2DBNActiv(nn.Module):
30 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
31 | super(SeperableConv2DBNActiv, self).__init__()
32 | self.conv = nn.Sequential(
33 | nn.Conv2d(
34 | nin,
35 | nin,
36 | kernel_size=ksize,
37 | stride=stride,
38 | padding=pad,
39 | dilation=dilation,
40 | groups=nin,
41 | bias=False,
42 | ),
43 | nn.Conv2d(nin, nout, kernel_size=1, bias=False),
44 | nn.BatchNorm2d(nout),
45 | activ(),
46 | )
47 |
48 | def __call__(self, x):
49 | return self.conv(x)
50 |
51 |
52 | class Encoder(nn.Module):
53 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.LeakyReLU):
54 | super(Encoder, self).__init__()
55 | self.conv1 = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
56 | self.conv2 = Conv2DBNActiv(nout, nout, ksize, stride, pad, activ=activ)
57 |
58 | def __call__(self, x):
59 | skip = self.conv1(x)
60 | h = self.conv2(skip)
61 |
62 | return h, skip
63 |
64 |
65 | class Decoder(nn.Module):
66 | def __init__(
67 | self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.ReLU, dropout=False
68 | ):
69 | super(Decoder, self).__init__()
70 | self.conv = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
71 | self.dropout = nn.Dropout2d(0.1) if dropout else None
72 |
73 | def __call__(self, x, skip=None):
74 | x = F.interpolate(x, scale_factor=2, mode="bilinear", align_corners=True)
75 | if skip is not None:
76 | skip = spec_utils.crop_center(skip, x)
77 | x = torch.cat([x, skip], dim=1)
78 | h = self.conv(x)
79 |
80 | if self.dropout is not None:
81 | h = self.dropout(h)
82 |
83 | return h
84 |
85 |
86 | class ASPPModule(nn.Module):
87 | def __init__(self, nin, nout, dilations=(4, 8, 16), activ=nn.ReLU):
88 | super(ASPPModule, self).__init__()
89 | self.conv1 = nn.Sequential(
90 | nn.AdaptiveAvgPool2d((1, None)),
91 | Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ),
92 | )
93 | self.conv2 = Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ)
94 | self.conv3 = SeperableConv2DBNActiv(
95 | nin, nin, 3, 1, dilations[0], dilations[0], activ=activ
96 | )
97 | self.conv4 = SeperableConv2DBNActiv(
98 | nin, nin, 3, 1, dilations[1], dilations[1], activ=activ
99 | )
100 | self.conv5 = SeperableConv2DBNActiv(
101 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
102 | )
103 | self.bottleneck = nn.Sequential(
104 | Conv2DBNActiv(nin * 5, nout, 1, 1, 0, activ=activ), nn.Dropout2d(0.1)
105 | )
106 |
107 | def forward(self, x):
108 | _, _, h, w = x.size()
109 | feat1 = F.interpolate(
110 | self.conv1(x), size=(h, w), mode="bilinear", align_corners=True
111 | )
112 | feat2 = self.conv2(x)
113 | feat3 = self.conv3(x)
114 | feat4 = self.conv4(x)
115 | feat5 = self.conv5(x)
116 | out = torch.cat((feat1, feat2, feat3, feat4, feat5), dim=1)
117 | bottle = self.bottleneck(out)
118 | return bottle
119 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/layers_33966KB.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import spec_utils
6 |
7 |
8 | class Conv2DBNActiv(nn.Module):
9 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
10 | super(Conv2DBNActiv, self).__init__()
11 | self.conv = nn.Sequential(
12 | nn.Conv2d(
13 | nin,
14 | nout,
15 | kernel_size=ksize,
16 | stride=stride,
17 | padding=pad,
18 | dilation=dilation,
19 | bias=False,
20 | ),
21 | nn.BatchNorm2d(nout),
22 | activ(),
23 | )
24 |
25 | def __call__(self, x):
26 | return self.conv(x)
27 |
28 |
29 | class SeperableConv2DBNActiv(nn.Module):
30 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
31 | super(SeperableConv2DBNActiv, self).__init__()
32 | self.conv = nn.Sequential(
33 | nn.Conv2d(
34 | nin,
35 | nin,
36 | kernel_size=ksize,
37 | stride=stride,
38 | padding=pad,
39 | dilation=dilation,
40 | groups=nin,
41 | bias=False,
42 | ),
43 | nn.Conv2d(nin, nout, kernel_size=1, bias=False),
44 | nn.BatchNorm2d(nout),
45 | activ(),
46 | )
47 |
48 | def __call__(self, x):
49 | return self.conv(x)
50 |
51 |
52 | class Encoder(nn.Module):
53 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.LeakyReLU):
54 | super(Encoder, self).__init__()
55 | self.conv1 = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
56 | self.conv2 = Conv2DBNActiv(nout, nout, ksize, stride, pad, activ=activ)
57 |
58 | def __call__(self, x):
59 | skip = self.conv1(x)
60 | h = self.conv2(skip)
61 |
62 | return h, skip
63 |
64 |
65 | class Decoder(nn.Module):
66 | def __init__(
67 | self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.ReLU, dropout=False
68 | ):
69 | super(Decoder, self).__init__()
70 | self.conv = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
71 | self.dropout = nn.Dropout2d(0.1) if dropout else None
72 |
73 | def __call__(self, x, skip=None):
74 | x = F.interpolate(x, scale_factor=2, mode="bilinear", align_corners=True)
75 | if skip is not None:
76 | skip = spec_utils.crop_center(skip, x)
77 | x = torch.cat([x, skip], dim=1)
78 | h = self.conv(x)
79 |
80 | if self.dropout is not None:
81 | h = self.dropout(h)
82 |
83 | return h
84 |
85 |
86 | class ASPPModule(nn.Module):
87 | def __init__(self, nin, nout, dilations=(4, 8, 16, 32, 64), activ=nn.ReLU):
88 | super(ASPPModule, self).__init__()
89 | self.conv1 = nn.Sequential(
90 | nn.AdaptiveAvgPool2d((1, None)),
91 | Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ),
92 | )
93 | self.conv2 = Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ)
94 | self.conv3 = SeperableConv2DBNActiv(
95 | nin, nin, 3, 1, dilations[0], dilations[0], activ=activ
96 | )
97 | self.conv4 = SeperableConv2DBNActiv(
98 | nin, nin, 3, 1, dilations[1], dilations[1], activ=activ
99 | )
100 | self.conv5 = SeperableConv2DBNActiv(
101 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
102 | )
103 | self.conv6 = SeperableConv2DBNActiv(
104 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
105 | )
106 | self.conv7 = SeperableConv2DBNActiv(
107 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
108 | )
109 | self.bottleneck = nn.Sequential(
110 | Conv2DBNActiv(nin * 7, nout, 1, 1, 0, activ=activ), nn.Dropout2d(0.1)
111 | )
112 |
113 | def forward(self, x):
114 | _, _, h, w = x.size()
115 | feat1 = F.interpolate(
116 | self.conv1(x), size=(h, w), mode="bilinear", align_corners=True
117 | )
118 | feat2 = self.conv2(x)
119 | feat3 = self.conv3(x)
120 | feat4 = self.conv4(x)
121 | feat5 = self.conv5(x)
122 | feat6 = self.conv6(x)
123 | feat7 = self.conv7(x)
124 | out = torch.cat((feat1, feat2, feat3, feat4, feat5, feat6, feat7), dim=1)
125 | bottle = self.bottleneck(out)
126 | return bottle
127 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/layers_537238KB.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import spec_utils
6 |
7 |
8 | class Conv2DBNActiv(nn.Module):
9 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
10 | super(Conv2DBNActiv, self).__init__()
11 | self.conv = nn.Sequential(
12 | nn.Conv2d(
13 | nin,
14 | nout,
15 | kernel_size=ksize,
16 | stride=stride,
17 | padding=pad,
18 | dilation=dilation,
19 | bias=False,
20 | ),
21 | nn.BatchNorm2d(nout),
22 | activ(),
23 | )
24 |
25 | def __call__(self, x):
26 | return self.conv(x)
27 |
28 |
29 | class SeperableConv2DBNActiv(nn.Module):
30 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, dilation=1, activ=nn.ReLU):
31 | super(SeperableConv2DBNActiv, self).__init__()
32 | self.conv = nn.Sequential(
33 | nn.Conv2d(
34 | nin,
35 | nin,
36 | kernel_size=ksize,
37 | stride=stride,
38 | padding=pad,
39 | dilation=dilation,
40 | groups=nin,
41 | bias=False,
42 | ),
43 | nn.Conv2d(nin, nout, kernel_size=1, bias=False),
44 | nn.BatchNorm2d(nout),
45 | activ(),
46 | )
47 |
48 | def __call__(self, x):
49 | return self.conv(x)
50 |
51 |
52 | class Encoder(nn.Module):
53 | def __init__(self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.LeakyReLU):
54 | super(Encoder, self).__init__()
55 | self.conv1 = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
56 | self.conv2 = Conv2DBNActiv(nout, nout, ksize, stride, pad, activ=activ)
57 |
58 | def __call__(self, x):
59 | skip = self.conv1(x)
60 | h = self.conv2(skip)
61 |
62 | return h, skip
63 |
64 |
65 | class Decoder(nn.Module):
66 | def __init__(
67 | self, nin, nout, ksize=3, stride=1, pad=1, activ=nn.ReLU, dropout=False
68 | ):
69 | super(Decoder, self).__init__()
70 | self.conv = Conv2DBNActiv(nin, nout, ksize, 1, pad, activ=activ)
71 | self.dropout = nn.Dropout2d(0.1) if dropout else None
72 |
73 | def __call__(self, x, skip=None):
74 | x = F.interpolate(x, scale_factor=2, mode="bilinear", align_corners=True)
75 | if skip is not None:
76 | skip = spec_utils.crop_center(skip, x)
77 | x = torch.cat([x, skip], dim=1)
78 | h = self.conv(x)
79 |
80 | if self.dropout is not None:
81 | h = self.dropout(h)
82 |
83 | return h
84 |
85 |
86 | class ASPPModule(nn.Module):
87 | def __init__(self, nin, nout, dilations=(4, 8, 16, 32, 64), activ=nn.ReLU):
88 | super(ASPPModule, self).__init__()
89 | self.conv1 = nn.Sequential(
90 | nn.AdaptiveAvgPool2d((1, None)),
91 | Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ),
92 | )
93 | self.conv2 = Conv2DBNActiv(nin, nin, 1, 1, 0, activ=activ)
94 | self.conv3 = SeperableConv2DBNActiv(
95 | nin, nin, 3, 1, dilations[0], dilations[0], activ=activ
96 | )
97 | self.conv4 = SeperableConv2DBNActiv(
98 | nin, nin, 3, 1, dilations[1], dilations[1], activ=activ
99 | )
100 | self.conv5 = SeperableConv2DBNActiv(
101 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
102 | )
103 | self.conv6 = SeperableConv2DBNActiv(
104 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
105 | )
106 | self.conv7 = SeperableConv2DBNActiv(
107 | nin, nin, 3, 1, dilations[2], dilations[2], activ=activ
108 | )
109 | self.bottleneck = nn.Sequential(
110 | Conv2DBNActiv(nin * 7, nout, 1, 1, 0, activ=activ), nn.Dropout2d(0.1)
111 | )
112 |
113 | def forward(self, x):
114 | _, _, h, w = x.size()
115 | feat1 = F.interpolate(
116 | self.conv1(x), size=(h, w), mode="bilinear", align_corners=True
117 | )
118 | feat2 = self.conv2(x)
119 | feat3 = self.conv3(x)
120 | feat4 = self.conv4(x)
121 | feat5 = self.conv5(x)
122 | feat6 = self.conv6(x)
123 | feat7 = self.conv7(x)
124 | out = torch.cat((feat1, feat2, feat3, feat4, feat5, feat6, feat7), dim=1)
125 | bottle = self.bottleneck(out)
126 | return bottle
127 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/model_param_init.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import pathlib
4 |
5 | default_param = {}
6 | default_param["bins"] = 768
7 | default_param["unstable_bins"] = 9 # training only
8 | default_param["reduction_bins"] = 762 # training only
9 | default_param["sr"] = 44100
10 | default_param["pre_filter_start"] = 757
11 | default_param["pre_filter_stop"] = 768
12 | default_param["band"] = {}
13 |
14 |
15 | default_param["band"][1] = {
16 | "sr": 11025,
17 | "hl": 128,
18 | "n_fft": 960,
19 | "crop_start": 0,
20 | "crop_stop": 245,
21 | "lpf_start": 61, # inference only
22 | "res_type": "polyphase",
23 | }
24 |
25 | default_param["band"][2] = {
26 | "sr": 44100,
27 | "hl": 512,
28 | "n_fft": 1536,
29 | "crop_start": 24,
30 | "crop_stop": 547,
31 | "hpf_start": 81, # inference only
32 | "res_type": "sinc_best",
33 | }
34 |
35 |
36 | def int_keys(d):
37 | r = {}
38 | for k, v in d:
39 | if k.isdigit():
40 | k = int(k)
41 | r[k] = v
42 | return r
43 |
44 |
45 | class ModelParameters(object):
46 | def __init__(self, config_path=""):
47 | if ".pth" == pathlib.Path(config_path).suffix:
48 | import zipfile
49 |
50 | with zipfile.ZipFile(config_path, "r") as zip:
51 | self.param = json.loads(
52 | zip.read("param.json"), object_pairs_hook=int_keys
53 | )
54 | elif ".json" == pathlib.Path(config_path).suffix:
55 | with open(config_path, "r") as f:
56 | self.param = json.loads(f.read(), object_pairs_hook=int_keys)
57 | else:
58 | self.param = default_param
59 |
60 | for k in [
61 | "mid_side",
62 | "mid_side_b",
63 | "mid_side_b2",
64 | "stereo_w",
65 | "stereo_n",
66 | "reverse",
67 | ]:
68 | if not k in self.param:
69 | self.param[k] = False
70 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr16000_hl512.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 16000,
8 | "hl": 512,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 1024,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 16000,
17 | "pre_filter_start": 1023,
18 | "pre_filter_stop": 1024
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr32000_hl512.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 32000,
8 | "hl": 512,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 1024,
12 | "hpf_start": -1,
13 | "res_type": "kaiser_fast"
14 | }
15 | },
16 | "sr": 32000,
17 | "pre_filter_start": 1000,
18 | "pre_filter_stop": 1021
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr33075_hl384.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 33075,
8 | "hl": 384,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 1024,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 33075,
17 | "pre_filter_start": 1000,
18 | "pre_filter_stop": 1021
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr44100_hl1024.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 44100,
8 | "hl": 1024,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 1024,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 44100,
17 | "pre_filter_start": 1023,
18 | "pre_filter_stop": 1024
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr44100_hl256.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 256,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 44100,
8 | "hl": 256,
9 | "n_fft": 512,
10 | "crop_start": 0,
11 | "crop_stop": 256,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 44100,
17 | "pre_filter_start": 256,
18 | "pre_filter_stop": 256
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr44100_hl512.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 44100,
8 | "hl": 512,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 1024,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 44100,
17 | "pre_filter_start": 1023,
18 | "pre_filter_stop": 1024
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/1band_sr44100_hl512_cut.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 1024,
3 | "unstable_bins": 0,
4 | "reduction_bins": 0,
5 | "band": {
6 | "1": {
7 | "sr": 44100,
8 | "hl": 512,
9 | "n_fft": 2048,
10 | "crop_start": 0,
11 | "crop_stop": 700,
12 | "hpf_start": -1,
13 | "res_type": "sinc_best"
14 | }
15 | },
16 | "sr": 44100,
17 | "pre_filter_start": 1023,
18 | "pre_filter_stop": 700
19 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/2band_32000.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 768,
3 | "unstable_bins": 7,
4 | "reduction_bins": 705,
5 | "band": {
6 | "1": {
7 | "sr": 6000,
8 | "hl": 66,
9 | "n_fft": 512,
10 | "crop_start": 0,
11 | "crop_stop": 240,
12 | "lpf_start": 60,
13 | "lpf_stop": 118,
14 | "res_type": "sinc_fastest"
15 | },
16 | "2": {
17 | "sr": 32000,
18 | "hl": 352,
19 | "n_fft": 1024,
20 | "crop_start": 22,
21 | "crop_stop": 505,
22 | "hpf_start": 44,
23 | "hpf_stop": 23,
24 | "res_type": "sinc_medium"
25 | }
26 | },
27 | "sr": 32000,
28 | "pre_filter_start": 710,
29 | "pre_filter_stop": 731
30 | }
31 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/2band_44100_lofi.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 512,
3 | "unstable_bins": 7,
4 | "reduction_bins": 510,
5 | "band": {
6 | "1": {
7 | "sr": 11025,
8 | "hl": 160,
9 | "n_fft": 768,
10 | "crop_start": 0,
11 | "crop_stop": 192,
12 | "lpf_start": 41,
13 | "lpf_stop": 139,
14 | "res_type": "sinc_fastest"
15 | },
16 | "2": {
17 | "sr": 44100,
18 | "hl": 640,
19 | "n_fft": 1024,
20 | "crop_start": 10,
21 | "crop_stop": 320,
22 | "hpf_start": 47,
23 | "hpf_stop": 15,
24 | "res_type": "sinc_medium"
25 | }
26 | },
27 | "sr": 44100,
28 | "pre_filter_start": 510,
29 | "pre_filter_stop": 512
30 | }
31 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/2band_48000.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 768,
3 | "unstable_bins": 7,
4 | "reduction_bins": 705,
5 | "band": {
6 | "1": {
7 | "sr": 6000,
8 | "hl": 66,
9 | "n_fft": 512,
10 | "crop_start": 0,
11 | "crop_stop": 240,
12 | "lpf_start": 60,
13 | "lpf_stop": 240,
14 | "res_type": "sinc_fastest"
15 | },
16 | "2": {
17 | "sr": 48000,
18 | "hl": 528,
19 | "n_fft": 1536,
20 | "crop_start": 22,
21 | "crop_stop": 505,
22 | "hpf_start": 82,
23 | "hpf_stop": 22,
24 | "res_type": "sinc_medium"
25 | }
26 | },
27 | "sr": 48000,
28 | "pre_filter_start": 710,
29 | "pre_filter_stop": 731
30 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/3band_44100.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 768,
3 | "unstable_bins": 5,
4 | "reduction_bins": 733,
5 | "band": {
6 | "1": {
7 | "sr": 11025,
8 | "hl": 128,
9 | "n_fft": 768,
10 | "crop_start": 0,
11 | "crop_stop": 278,
12 | "lpf_start": 28,
13 | "lpf_stop": 140,
14 | "res_type": "polyphase"
15 | },
16 | "2": {
17 | "sr": 22050,
18 | "hl": 256,
19 | "n_fft": 768,
20 | "crop_start": 14,
21 | "crop_stop": 322,
22 | "hpf_start": 70,
23 | "hpf_stop": 14,
24 | "lpf_start": 283,
25 | "lpf_stop": 314,
26 | "res_type": "polyphase"
27 | },
28 | "3": {
29 | "sr": 44100,
30 | "hl": 512,
31 | "n_fft": 768,
32 | "crop_start": 131,
33 | "crop_stop": 313,
34 | "hpf_start": 154,
35 | "hpf_stop": 141,
36 | "res_type": "sinc_medium"
37 | }
38 | },
39 | "sr": 44100,
40 | "pre_filter_start": 757,
41 | "pre_filter_stop": 768
42 | }
43 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/3band_44100_mid.json:
--------------------------------------------------------------------------------
1 | {
2 | "mid_side": true,
3 | "bins": 768,
4 | "unstable_bins": 5,
5 | "reduction_bins": 733,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 768,
11 | "crop_start": 0,
12 | "crop_stop": 278,
13 | "lpf_start": 28,
14 | "lpf_stop": 140,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 22050,
19 | "hl": 256,
20 | "n_fft": 768,
21 | "crop_start": 14,
22 | "crop_stop": 322,
23 | "hpf_start": 70,
24 | "hpf_stop": 14,
25 | "lpf_start": 283,
26 | "lpf_stop": 314,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 44100,
31 | "hl": 512,
32 | "n_fft": 768,
33 | "crop_start": 131,
34 | "crop_stop": 313,
35 | "hpf_start": 154,
36 | "hpf_stop": 141,
37 | "res_type": "sinc_medium"
38 | }
39 | },
40 | "sr": 44100,
41 | "pre_filter_start": 757,
42 | "pre_filter_stop": 768
43 | }
44 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/3band_44100_msb2.json:
--------------------------------------------------------------------------------
1 | {
2 | "mid_side_b2": true,
3 | "bins": 640,
4 | "unstable_bins": 7,
5 | "reduction_bins": 565,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 108,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 187,
13 | "lpf_start": 92,
14 | "lpf_stop": 186,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 22050,
19 | "hl": 216,
20 | "n_fft": 768,
21 | "crop_start": 0,
22 | "crop_stop": 212,
23 | "hpf_start": 68,
24 | "hpf_stop": 34,
25 | "lpf_start": 174,
26 | "lpf_stop": 209,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 44100,
31 | "hl": 432,
32 | "n_fft": 640,
33 | "crop_start": 66,
34 | "crop_stop": 307,
35 | "hpf_start": 86,
36 | "hpf_stop": 72,
37 | "res_type": "kaiser_fast"
38 | }
39 | },
40 | "sr": 44100,
41 | "pre_filter_start": 639,
42 | "pre_filter_stop": 640
43 | }
44 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 768,
3 | "unstable_bins": 7,
4 | "reduction_bins": 668,
5 | "band": {
6 | "1": {
7 | "sr": 11025,
8 | "hl": 128,
9 | "n_fft": 1024,
10 | "crop_start": 0,
11 | "crop_stop": 186,
12 | "lpf_start": 37,
13 | "lpf_stop": 73,
14 | "res_type": "polyphase"
15 | },
16 | "2": {
17 | "sr": 11025,
18 | "hl": 128,
19 | "n_fft": 512,
20 | "crop_start": 4,
21 | "crop_stop": 185,
22 | "hpf_start": 36,
23 | "hpf_stop": 18,
24 | "lpf_start": 93,
25 | "lpf_stop": 185,
26 | "res_type": "polyphase"
27 | },
28 | "3": {
29 | "sr": 22050,
30 | "hl": 256,
31 | "n_fft": 512,
32 | "crop_start": 46,
33 | "crop_stop": 186,
34 | "hpf_start": 93,
35 | "hpf_stop": 46,
36 | "lpf_start": 164,
37 | "lpf_stop": 186,
38 | "res_type": "polyphase"
39 | },
40 | "4": {
41 | "sr": 44100,
42 | "hl": 512,
43 | "n_fft": 768,
44 | "crop_start": 121,
45 | "crop_stop": 382,
46 | "hpf_start": 138,
47 | "hpf_stop": 123,
48 | "res_type": "sinc_medium"
49 | }
50 | },
51 | "sr": 44100,
52 | "pre_filter_start": 740,
53 | "pre_filter_stop": 768
54 | }
55 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100_mid.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 768,
3 | "unstable_bins": 7,
4 | "mid_side": true,
5 | "reduction_bins": 668,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 186,
13 | "lpf_start": 37,
14 | "lpf_stop": 73,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 11025,
19 | "hl": 128,
20 | "n_fft": 512,
21 | "crop_start": 4,
22 | "crop_stop": 185,
23 | "hpf_start": 36,
24 | "hpf_stop": 18,
25 | "lpf_start": 93,
26 | "lpf_stop": 185,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 22050,
31 | "hl": 256,
32 | "n_fft": 512,
33 | "crop_start": 46,
34 | "crop_stop": 186,
35 | "hpf_start": 93,
36 | "hpf_stop": 46,
37 | "lpf_start": 164,
38 | "lpf_stop": 186,
39 | "res_type": "polyphase"
40 | },
41 | "4": {
42 | "sr": 44100,
43 | "hl": 512,
44 | "n_fft": 768,
45 | "crop_start": 121,
46 | "crop_stop": 382,
47 | "hpf_start": 138,
48 | "hpf_stop": 123,
49 | "res_type": "sinc_medium"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 740,
54 | "pre_filter_stop": 768
55 | }
56 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100_msb.json:
--------------------------------------------------------------------------------
1 | {
2 | "mid_side_b": true,
3 | "bins": 768,
4 | "unstable_bins": 7,
5 | "reduction_bins": 668,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 186,
13 | "lpf_start": 37,
14 | "lpf_stop": 73,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 11025,
19 | "hl": 128,
20 | "n_fft": 512,
21 | "crop_start": 4,
22 | "crop_stop": 185,
23 | "hpf_start": 36,
24 | "hpf_stop": 18,
25 | "lpf_start": 93,
26 | "lpf_stop": 185,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 22050,
31 | "hl": 256,
32 | "n_fft": 512,
33 | "crop_start": 46,
34 | "crop_stop": 186,
35 | "hpf_start": 93,
36 | "hpf_stop": 46,
37 | "lpf_start": 164,
38 | "lpf_stop": 186,
39 | "res_type": "polyphase"
40 | },
41 | "4": {
42 | "sr": 44100,
43 | "hl": 512,
44 | "n_fft": 768,
45 | "crop_start": 121,
46 | "crop_stop": 382,
47 | "hpf_start": 138,
48 | "hpf_stop": 123,
49 | "res_type": "sinc_medium"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 740,
54 | "pre_filter_stop": 768
55 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100_msb2.json:
--------------------------------------------------------------------------------
1 | {
2 | "mid_side_b": true,
3 | "bins": 768,
4 | "unstable_bins": 7,
5 | "reduction_bins": 668,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 186,
13 | "lpf_start": 37,
14 | "lpf_stop": 73,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 11025,
19 | "hl": 128,
20 | "n_fft": 512,
21 | "crop_start": 4,
22 | "crop_stop": 185,
23 | "hpf_start": 36,
24 | "hpf_stop": 18,
25 | "lpf_start": 93,
26 | "lpf_stop": 185,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 22050,
31 | "hl": 256,
32 | "n_fft": 512,
33 | "crop_start": 46,
34 | "crop_stop": 186,
35 | "hpf_start": 93,
36 | "hpf_stop": 46,
37 | "lpf_start": 164,
38 | "lpf_stop": 186,
39 | "res_type": "polyphase"
40 | },
41 | "4": {
42 | "sr": 44100,
43 | "hl": 512,
44 | "n_fft": 768,
45 | "crop_start": 121,
46 | "crop_stop": 382,
47 | "hpf_start": 138,
48 | "hpf_stop": 123,
49 | "res_type": "sinc_medium"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 740,
54 | "pre_filter_stop": 768
55 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100_reverse.json:
--------------------------------------------------------------------------------
1 | {
2 | "reverse": true,
3 | "bins": 768,
4 | "unstable_bins": 7,
5 | "reduction_bins": 668,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 186,
13 | "lpf_start": 37,
14 | "lpf_stop": 73,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 11025,
19 | "hl": 128,
20 | "n_fft": 512,
21 | "crop_start": 4,
22 | "crop_stop": 185,
23 | "hpf_start": 36,
24 | "hpf_stop": 18,
25 | "lpf_start": 93,
26 | "lpf_stop": 185,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 22050,
31 | "hl": 256,
32 | "n_fft": 512,
33 | "crop_start": 46,
34 | "crop_stop": 186,
35 | "hpf_start": 93,
36 | "hpf_stop": 46,
37 | "lpf_start": 164,
38 | "lpf_stop": 186,
39 | "res_type": "polyphase"
40 | },
41 | "4": {
42 | "sr": 44100,
43 | "hl": 512,
44 | "n_fft": 768,
45 | "crop_start": 121,
46 | "crop_stop": 382,
47 | "hpf_start": 138,
48 | "hpf_stop": 123,
49 | "res_type": "sinc_medium"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 740,
54 | "pre_filter_stop": 768
55 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_44100_sw.json:
--------------------------------------------------------------------------------
1 | {
2 | "stereo_w": true,
3 | "bins": 768,
4 | "unstable_bins": 7,
5 | "reduction_bins": 668,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 128,
10 | "n_fft": 1024,
11 | "crop_start": 0,
12 | "crop_stop": 186,
13 | "lpf_start": 37,
14 | "lpf_stop": 73,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 11025,
19 | "hl": 128,
20 | "n_fft": 512,
21 | "crop_start": 4,
22 | "crop_stop": 185,
23 | "hpf_start": 36,
24 | "hpf_stop": 18,
25 | "lpf_start": 93,
26 | "lpf_stop": 185,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 22050,
31 | "hl": 256,
32 | "n_fft": 512,
33 | "crop_start": 46,
34 | "crop_stop": 186,
35 | "hpf_start": 93,
36 | "hpf_stop": 46,
37 | "lpf_start": 164,
38 | "lpf_stop": 186,
39 | "res_type": "polyphase"
40 | },
41 | "4": {
42 | "sr": 44100,
43 | "hl": 512,
44 | "n_fft": 768,
45 | "crop_start": 121,
46 | "crop_stop": 382,
47 | "hpf_start": 138,
48 | "hpf_stop": 123,
49 | "res_type": "sinc_medium"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 740,
54 | "pre_filter_stop": 768
55 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_v2.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 672,
3 | "unstable_bins": 8,
4 | "reduction_bins": 637,
5 | "band": {
6 | "1": {
7 | "sr": 7350,
8 | "hl": 80,
9 | "n_fft": 640,
10 | "crop_start": 0,
11 | "crop_stop": 85,
12 | "lpf_start": 25,
13 | "lpf_stop": 53,
14 | "res_type": "polyphase"
15 | },
16 | "2": {
17 | "sr": 7350,
18 | "hl": 80,
19 | "n_fft": 320,
20 | "crop_start": 4,
21 | "crop_stop": 87,
22 | "hpf_start": 25,
23 | "hpf_stop": 12,
24 | "lpf_start": 31,
25 | "lpf_stop": 62,
26 | "res_type": "polyphase"
27 | },
28 | "3": {
29 | "sr": 14700,
30 | "hl": 160,
31 | "n_fft": 512,
32 | "crop_start": 17,
33 | "crop_stop": 216,
34 | "hpf_start": 48,
35 | "hpf_stop": 24,
36 | "lpf_start": 139,
37 | "lpf_stop": 210,
38 | "res_type": "polyphase"
39 | },
40 | "4": {
41 | "sr": 44100,
42 | "hl": 480,
43 | "n_fft": 960,
44 | "crop_start": 78,
45 | "crop_stop": 383,
46 | "hpf_start": 130,
47 | "hpf_stop": 86,
48 | "res_type": "kaiser_fast"
49 | }
50 | },
51 | "sr": 44100,
52 | "pre_filter_start": 668,
53 | "pre_filter_stop": 672
54 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_v2_sn.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 672,
3 | "unstable_bins": 8,
4 | "reduction_bins": 637,
5 | "band": {
6 | "1": {
7 | "sr": 7350,
8 | "hl": 80,
9 | "n_fft": 640,
10 | "crop_start": 0,
11 | "crop_stop": 85,
12 | "lpf_start": 25,
13 | "lpf_stop": 53,
14 | "res_type": "polyphase"
15 | },
16 | "2": {
17 | "sr": 7350,
18 | "hl": 80,
19 | "n_fft": 320,
20 | "crop_start": 4,
21 | "crop_stop": 87,
22 | "hpf_start": 25,
23 | "hpf_stop": 12,
24 | "lpf_start": 31,
25 | "lpf_stop": 62,
26 | "res_type": "polyphase"
27 | },
28 | "3": {
29 | "sr": 14700,
30 | "hl": 160,
31 | "n_fft": 512,
32 | "crop_start": 17,
33 | "crop_stop": 216,
34 | "hpf_start": 48,
35 | "hpf_stop": 24,
36 | "lpf_start": 139,
37 | "lpf_stop": 210,
38 | "res_type": "polyphase"
39 | },
40 | "4": {
41 | "sr": 44100,
42 | "hl": 480,
43 | "n_fft": 960,
44 | "crop_start": 78,
45 | "crop_stop": 383,
46 | "hpf_start": 130,
47 | "hpf_stop": 86,
48 | "convert_channels": "stereo_n",
49 | "res_type": "kaiser_fast"
50 | }
51 | },
52 | "sr": 44100,
53 | "pre_filter_start": 668,
54 | "pre_filter_stop": 672
55 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/4band_v3.json:
--------------------------------------------------------------------------------
1 | {
2 | "bins": 672,
3 | "unstable_bins": 8,
4 | "reduction_bins": 530,
5 | "band": {
6 | "1": {
7 | "sr": 7350,
8 | "hl": 80,
9 | "n_fft": 640,
10 | "crop_start": 0,
11 | "crop_stop": 85,
12 | "lpf_start": 25,
13 | "lpf_stop": 53,
14 | "res_type": "polyphase"
15 | },
16 | "2": {
17 | "sr": 7350,
18 | "hl": 80,
19 | "n_fft": 320,
20 | "crop_start": 4,
21 | "crop_stop": 87,
22 | "hpf_start": 25,
23 | "hpf_stop": 12,
24 | "lpf_start": 31,
25 | "lpf_stop": 62,
26 | "res_type": "polyphase"
27 | },
28 | "3": {
29 | "sr": 14700,
30 | "hl": 160,
31 | "n_fft": 512,
32 | "crop_start": 17,
33 | "crop_stop": 216,
34 | "hpf_start": 48,
35 | "hpf_stop": 24,
36 | "lpf_start": 139,
37 | "lpf_stop": 210,
38 | "res_type": "polyphase"
39 | },
40 | "4": {
41 | "sr": 44100,
42 | "hl": 480,
43 | "n_fft": 960,
44 | "crop_start": 78,
45 | "crop_stop": 383,
46 | "hpf_start": 130,
47 | "hpf_stop": 86,
48 | "res_type": "kaiser_fast"
49 | }
50 | },
51 | "sr": 44100,
52 | "pre_filter_start": 668,
53 | "pre_filter_stop": 672
54 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/modelparams/ensemble.json:
--------------------------------------------------------------------------------
1 | {
2 | "mid_side_b2": true,
3 | "bins": 1280,
4 | "unstable_bins": 7,
5 | "reduction_bins": 565,
6 | "band": {
7 | "1": {
8 | "sr": 11025,
9 | "hl": 108,
10 | "n_fft": 2048,
11 | "crop_start": 0,
12 | "crop_stop": 374,
13 | "lpf_start": 92,
14 | "lpf_stop": 186,
15 | "res_type": "polyphase"
16 | },
17 | "2": {
18 | "sr": 22050,
19 | "hl": 216,
20 | "n_fft": 1536,
21 | "crop_start": 0,
22 | "crop_stop": 424,
23 | "hpf_start": 68,
24 | "hpf_stop": 34,
25 | "lpf_start": 348,
26 | "lpf_stop": 418,
27 | "res_type": "polyphase"
28 | },
29 | "3": {
30 | "sr": 44100,
31 | "hl": 432,
32 | "n_fft": 1280,
33 | "crop_start": 132,
34 | "crop_stop": 614,
35 | "hpf_start": 172,
36 | "hpf_stop": 144,
37 | "res_type": "polyphase"
38 | }
39 | },
40 | "sr": 44100,
41 | "pre_filter_start": 1280,
42 | "pre_filter_stop": 1280
43 | }
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/nets.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import layers
6 |
7 |
8 | class BaseNet(nn.Module):
9 | def __init__(
10 | self, nin, nout, nin_lstm, nout_lstm, dilations=((4, 2), (8, 4), (12, 6))
11 | ):
12 | super(BaseNet, self).__init__()
13 | self.enc1 = layers.Conv2DBNActiv(nin, nout, 3, 1, 1)
14 | self.enc2 = layers.Encoder(nout, nout * 2, 3, 2, 1)
15 | self.enc3 = layers.Encoder(nout * 2, nout * 4, 3, 2, 1)
16 | self.enc4 = layers.Encoder(nout * 4, nout * 6, 3, 2, 1)
17 | self.enc5 = layers.Encoder(nout * 6, nout * 8, 3, 2, 1)
18 |
19 | self.aspp = layers.ASPPModule(nout * 8, nout * 8, dilations, dropout=True)
20 |
21 | self.dec4 = layers.Decoder(nout * (6 + 8), nout * 6, 3, 1, 1)
22 | self.dec3 = layers.Decoder(nout * (4 + 6), nout * 4, 3, 1, 1)
23 | self.dec2 = layers.Decoder(nout * (2 + 4), nout * 2, 3, 1, 1)
24 | self.lstm_dec2 = layers.LSTMModule(nout * 2, nin_lstm, nout_lstm)
25 | self.dec1 = layers.Decoder(nout * (1 + 2) + 1, nout * 1, 3, 1, 1)
26 |
27 | @torch.inference_mode()
28 | def forward(self, x):
29 | e1 = self.enc1(x)
30 | e2 = self.enc2(e1)
31 | e3 = self.enc3(e2)
32 | e4 = self.enc4(e3)
33 | e5 = self.enc5(e4)
34 |
35 | h = self.aspp(e5)
36 |
37 | h = self.dec4(h, e4)
38 | h = self.dec3(h, e3)
39 | h = self.dec2(h, e2)
40 | h = torch.cat([h, self.lstm_dec2(h)], dim=1)
41 | h = self.dec1(h, e1)
42 |
43 | return h
44 |
45 |
46 | class CascadedNet(nn.Module):
47 | def __init__(self, n_fft, nout=32, nout_lstm=128):
48 | super(CascadedNet, self).__init__()
49 |
50 | self.max_bin = n_fft // 2
51 | self.output_bin = n_fft // 2 + 1
52 | self.nin_lstm = self.max_bin // 2
53 | self.offset = 64
54 |
55 | self.stg1_low_band_net = nn.Sequential(
56 | BaseNet(2, nout // 2, self.nin_lstm // 2, nout_lstm),
57 | layers.Conv2DBNActiv(nout // 2, nout // 4, 1, 1, 0),
58 | )
59 |
60 | self.stg1_high_band_net = BaseNet(
61 | 2, nout // 4, self.nin_lstm // 2, nout_lstm // 2
62 | )
63 |
64 | self.stg2_low_band_net = nn.Sequential(
65 | BaseNet(nout // 4 + 2, nout, self.nin_lstm // 2, nout_lstm),
66 | layers.Conv2DBNActiv(nout, nout // 2, 1, 1, 0),
67 | )
68 | self.stg2_high_band_net = BaseNet(
69 | nout // 4 + 2, nout // 2, self.nin_lstm // 2, nout_lstm // 2
70 | )
71 |
72 | self.stg3_full_band_net = BaseNet(
73 | 3 * nout // 4 + 2, nout, self.nin_lstm, nout_lstm
74 | )
75 |
76 | self.out = nn.Conv2d(nout, 2, 1, bias=False)
77 | self.aux_out = nn.Conv2d(3 * nout // 4, 2, 1, bias=False)
78 |
79 | @torch.inference_mode()
80 | def forward(self, x):
81 | x = x[:, :, : self.max_bin]
82 |
83 | bandw = x.size()[2] // 2
84 | l1_in = x[:, :, :bandw]
85 | h1_in = x[:, :, bandw:]
86 | l1 = self.stg1_low_band_net(l1_in)
87 | h1 = self.stg1_high_band_net(h1_in)
88 | aux1 = torch.cat([l1, h1], dim=2)
89 |
90 | l2_in = torch.cat([l1_in, l1], dim=1)
91 | h2_in = torch.cat([h1_in, h1], dim=1)
92 | l2 = self.stg2_low_band_net(l2_in)
93 | h2 = self.stg2_high_band_net(h2_in)
94 | aux2 = torch.cat([l2, h2], dim=2)
95 |
96 | f3_in = torch.cat([x, aux1, aux2], dim=1)
97 | f3 = self.stg3_full_band_net(f3_in)
98 |
99 | mask = torch.sigmoid(self.out(f3))
100 | mask = F.pad(
101 | input=mask,
102 | pad=(0, 0, 0, self.output_bin - mask.size()[2]),
103 | mode="replicate",
104 | )
105 |
106 | if self.training:
107 | aux = torch.cat([aux1, aux2], dim=1)
108 | aux = torch.sigmoid(self.aux_out(aux))
109 | aux = F.pad(
110 | input=aux,
111 | pad=(0, 0, 0, self.output_bin - aux.size()[2]),
112 | mode="replicate",
113 | )
114 | return mask, aux
115 | else:
116 | return mask
117 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/nets_123821KB.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import layers_123821KB as layers
6 |
7 |
8 | class BaseASPPNet(nn.Module):
9 | def __init__(self, nin, ch, dilations=(4, 8, 16)):
10 | super(BaseASPPNet, self).__init__()
11 | self.enc1 = layers.Encoder(nin, ch, 3, 2, 1)
12 | self.enc2 = layers.Encoder(ch, ch * 2, 3, 2, 1)
13 | self.enc3 = layers.Encoder(ch * 2, ch * 4, 3, 2, 1)
14 | self.enc4 = layers.Encoder(ch * 4, ch * 8, 3, 2, 1)
15 |
16 | self.aspp = layers.ASPPModule(ch * 8, ch * 16, dilations)
17 |
18 | self.dec4 = layers.Decoder(ch * (8 + 16), ch * 8, 3, 1, 1)
19 | self.dec3 = layers.Decoder(ch * (4 + 8), ch * 4, 3, 1, 1)
20 | self.dec2 = layers.Decoder(ch * (2 + 4), ch * 2, 3, 1, 1)
21 | self.dec1 = layers.Decoder(ch * (1 + 2), ch, 3, 1, 1)
22 |
23 | def __call__(self, x):
24 | h, e1 = self.enc1(x)
25 | h, e2 = self.enc2(h)
26 | h, e3 = self.enc3(h)
27 | h, e4 = self.enc4(h)
28 |
29 | h = self.aspp(h)
30 |
31 | h = self.dec4(h, e4)
32 | h = self.dec3(h, e3)
33 | h = self.dec2(h, e2)
34 | h = self.dec1(h, e1)
35 |
36 | return h
37 |
38 |
39 | class CascadedASPPNet(nn.Module):
40 | def __init__(self, n_fft):
41 | super(CascadedASPPNet, self).__init__()
42 | self.stg1_low_band_net = BaseASPPNet(2, 32)
43 | self.stg1_high_band_net = BaseASPPNet(2, 32)
44 |
45 | self.stg2_bridge = layers.Conv2DBNActiv(34, 16, 1, 1, 0)
46 | self.stg2_full_band_net = BaseASPPNet(16, 32)
47 |
48 | self.stg3_bridge = layers.Conv2DBNActiv(66, 32, 1, 1, 0)
49 | self.stg3_full_band_net = BaseASPPNet(32, 64)
50 |
51 | self.out = nn.Conv2d(64, 2, 1, bias=False)
52 | self.aux1_out = nn.Conv2d(32, 2, 1, bias=False)
53 | self.aux2_out = nn.Conv2d(32, 2, 1, bias=False)
54 |
55 | self.max_bin = n_fft // 2
56 | self.output_bin = n_fft // 2 + 1
57 |
58 | self.offset = 128
59 |
60 | def forward(self, x, aggressiveness=None):
61 | mix = x.detach()
62 | x = x.clone()
63 |
64 | x = x[:, :, : self.max_bin]
65 |
66 | bandw = x.size()[2] // 2
67 | aux1 = torch.cat(
68 | [
69 | self.stg1_low_band_net(x[:, :, :bandw]),
70 | self.stg1_high_band_net(x[:, :, bandw:]),
71 | ],
72 | dim=2,
73 | )
74 |
75 | h = torch.cat([x, aux1], dim=1)
76 | aux2 = self.stg2_full_band_net(self.stg2_bridge(h))
77 |
78 | h = torch.cat([x, aux1, aux2], dim=1)
79 | h = self.stg3_full_band_net(self.stg3_bridge(h))
80 |
81 | mask = torch.sigmoid(self.out(h))
82 | mask = F.pad(
83 | input=mask,
84 | pad=(0, 0, 0, self.output_bin - mask.size()[2]),
85 | mode="replicate",
86 | )
87 |
88 | if self.training:
89 | aux1 = torch.sigmoid(self.aux1_out(aux1))
90 | aux1 = F.pad(
91 | input=aux1,
92 | pad=(0, 0, 0, self.output_bin - aux1.size()[2]),
93 | mode="replicate",
94 | )
95 | aux2 = torch.sigmoid(self.aux2_out(aux2))
96 | aux2 = F.pad(
97 | input=aux2,
98 | pad=(0, 0, 0, self.output_bin - aux2.size()[2]),
99 | mode="replicate",
100 | )
101 | return mask * mix, aux1 * mix, aux2 * mix
102 | else:
103 | if aggressiveness:
104 | mask[:, :, : aggressiveness["split_bin"]] = torch.pow(
105 | mask[:, :, : aggressiveness["split_bin"]],
106 | 1 + aggressiveness["value"] / 3,
107 | )
108 | mask[:, :, aggressiveness["split_bin"] :] = torch.pow(
109 | mask[:, :, aggressiveness["split_bin"] :],
110 | 1 + aggressiveness["value"],
111 | )
112 |
113 | return mask * mix
114 |
115 | def predict(self, x_mag, aggressiveness=None):
116 | h = self.forward(x_mag, aggressiveness)
117 |
118 | if self.offset > 0:
119 | h = h[:, :, :, self.offset : -self.offset]
120 | assert h.size()[3] > 0
121 |
122 | return h
123 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/nets_33966KB.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn.functional as F
3 | from torch import nn
4 |
5 | from . import layers_33966KB as layers
6 |
7 |
8 | class BaseASPPNet(nn.Module):
9 | def __init__(self, nin, ch, dilations=(4, 8, 16, 32)):
10 | super(BaseASPPNet, self).__init__()
11 | self.enc1 = layers.Encoder(nin, ch, 3, 2, 1)
12 | self.enc2 = layers.Encoder(ch, ch * 2, 3, 2, 1)
13 | self.enc3 = layers.Encoder(ch * 2, ch * 4, 3, 2, 1)
14 | self.enc4 = layers.Encoder(ch * 4, ch * 8, 3, 2, 1)
15 |
16 | self.aspp = layers.ASPPModule(ch * 8, ch * 16, dilations)
17 |
18 | self.dec4 = layers.Decoder(ch * (8 + 16), ch * 8, 3, 1, 1)
19 | self.dec3 = layers.Decoder(ch * (4 + 8), ch * 4, 3, 1, 1)
20 | self.dec2 = layers.Decoder(ch * (2 + 4), ch * 2, 3, 1, 1)
21 | self.dec1 = layers.Decoder(ch * (1 + 2), ch, 3, 1, 1)
22 |
23 | def __call__(self, x):
24 | h, e1 = self.enc1(x)
25 | h, e2 = self.enc2(h)
26 | h, e3 = self.enc3(h)
27 | h, e4 = self.enc4(h)
28 |
29 | h = self.aspp(h)
30 |
31 | h = self.dec4(h, e4)
32 | h = self.dec3(h, e3)
33 | h = self.dec2(h, e2)
34 | h = self.dec1(h, e1)
35 |
36 | return h
37 |
38 |
39 | class CascadedASPPNet(nn.Module):
40 | def __init__(self, n_fft):
41 | super(CascadedASPPNet, self).__init__()
42 | self.stg1_low_band_net = BaseASPPNet(2, 16)
43 | self.stg1_high_band_net = BaseASPPNet(2, 16)
44 |
45 | self.stg2_bridge = layers.Conv2DBNActiv(18, 8, 1, 1, 0)
46 | self.stg2_full_band_net = BaseASPPNet(8, 16)
47 |
48 | self.stg3_bridge = layers.Conv2DBNActiv(34, 16, 1, 1, 0)
49 | self.stg3_full_band_net = BaseASPPNet(16, 32)
50 |
51 | self.out = nn.Conv2d(32, 2, 1, bias=False)
52 | self.aux1_out = nn.Conv2d(16, 2, 1, bias=False)
53 | self.aux2_out = nn.Conv2d(16, 2, 1, bias=False)
54 |
55 | self.max_bin = n_fft // 2
56 | self.output_bin = n_fft // 2 + 1
57 |
58 | self.offset = 128
59 |
60 | def forward(self, x, aggressiveness=None):
61 | mix = x.detach()
62 | x = x.clone()
63 |
64 | x = x[:, :, : self.max_bin]
65 |
66 | bandw = x.size()[2] // 2
67 | aux1 = torch.cat(
68 | [
69 | self.stg1_low_band_net(x[:, :, :bandw]),
70 | self.stg1_high_band_net(x[:, :, bandw:]),
71 | ],
72 | dim=2,
73 | )
74 |
75 | h = torch.cat([x, aux1], dim=1)
76 | aux2 = self.stg2_full_band_net(self.stg2_bridge(h))
77 |
78 | h = torch.cat([x, aux1, aux2], dim=1)
79 | h = self.stg3_full_band_net(self.stg3_bridge(h))
80 |
81 | mask = torch.sigmoid(self.out(h))
82 | mask = F.pad(
83 | input=mask,
84 | pad=(0, 0, 0, self.output_bin - mask.size()[2]),
85 | mode="replicate",
86 | )
87 |
88 | if self.training:
89 | aux1 = torch.sigmoid(self.aux1_out(aux1))
90 | aux1 = F.pad(
91 | input=aux1,
92 | pad=(0, 0, 0, self.output_bin - aux1.size()[2]),
93 | mode="replicate",
94 | )
95 | aux2 = torch.sigmoid(self.aux2_out(aux2))
96 | aux2 = F.pad(
97 | input=aux2,
98 | pad=(0, 0, 0, self.output_bin - aux2.size()[2]),
99 | mode="replicate",
100 | )
101 | return mask * mix, aux1 * mix, aux2 * mix
102 | else:
103 | if aggressiveness:
104 | mask[:, :, : aggressiveness["split_bin"]] = torch.pow(
105 | mask[:, :, : aggressiveness["split_bin"]],
106 | 1 + aggressiveness["value"] / 3,
107 | )
108 | mask[:, :, aggressiveness["split_bin"] :] = torch.pow(
109 | mask[:, :, aggressiveness["split_bin"] :],
110 | 1 + aggressiveness["value"],
111 | )
112 |
113 | return mask * mix
114 |
115 | def predict(self, x_mag, aggressiveness=None):
116 | h = self.forward(x_mag, aggressiveness)
117 |
118 | if self.offset > 0:
119 | h = h[:, :, :, self.offset : -self.offset]
120 | assert h.size()[3] > 0
121 |
122 | return h
123 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/lib_v5/nets_537238KB.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | import torch.nn.functional as F
4 | from torch import nn
5 |
6 | from . import layers_537238KB as layers
7 |
8 |
9 | class BaseASPPNet(nn.Module):
10 | def __init__(self, nin, ch, dilations=(4, 8, 16)):
11 | super(BaseASPPNet, self).__init__()
12 | self.enc1 = layers.Encoder(nin, ch, 3, 2, 1)
13 | self.enc2 = layers.Encoder(ch, ch * 2, 3, 2, 1)
14 | self.enc3 = layers.Encoder(ch * 2, ch * 4, 3, 2, 1)
15 | self.enc4 = layers.Encoder(ch * 4, ch * 8, 3, 2, 1)
16 |
17 | self.aspp = layers.ASPPModule(ch * 8, ch * 16, dilations)
18 |
19 | self.dec4 = layers.Decoder(ch * (8 + 16), ch * 8, 3, 1, 1)
20 | self.dec3 = layers.Decoder(ch * (4 + 8), ch * 4, 3, 1, 1)
21 | self.dec2 = layers.Decoder(ch * (2 + 4), ch * 2, 3, 1, 1)
22 | self.dec1 = layers.Decoder(ch * (1 + 2), ch, 3, 1, 1)
23 |
24 | def __call__(self, x):
25 | h, e1 = self.enc1(x)
26 | h, e2 = self.enc2(h)
27 | h, e3 = self.enc3(h)
28 | h, e4 = self.enc4(h)
29 |
30 | h = self.aspp(h)
31 |
32 | h = self.dec4(h, e4)
33 | h = self.dec3(h, e3)
34 | h = self.dec2(h, e2)
35 | h = self.dec1(h, e1)
36 |
37 | return h
38 |
39 |
40 | class CascadedASPPNet(nn.Module):
41 | def __init__(self, n_fft):
42 | super(CascadedASPPNet, self).__init__()
43 | self.stg1_low_band_net = BaseASPPNet(2, 64)
44 | self.stg1_high_band_net = BaseASPPNet(2, 64)
45 |
46 | self.stg2_bridge = layers.Conv2DBNActiv(66, 32, 1, 1, 0)
47 | self.stg2_full_band_net = BaseASPPNet(32, 64)
48 |
49 | self.stg3_bridge = layers.Conv2DBNActiv(130, 64, 1, 1, 0)
50 | self.stg3_full_band_net = BaseASPPNet(64, 128)
51 |
52 | self.out = nn.Conv2d(128, 2, 1, bias=False)
53 | self.aux1_out = nn.Conv2d(64, 2, 1, bias=False)
54 | self.aux2_out = nn.Conv2d(64, 2, 1, bias=False)
55 |
56 | self.max_bin = n_fft // 2
57 | self.output_bin = n_fft // 2 + 1
58 |
59 | self.offset = 128
60 |
61 | def forward(self, x, aggressiveness=None):
62 | mix = x.detach()
63 | x = x.clone()
64 |
65 | x = x[:, :, : self.max_bin]
66 |
67 | bandw = x.size()[2] // 2
68 | aux1 = torch.cat(
69 | [
70 | self.stg1_low_band_net(x[:, :, :bandw]),
71 | self.stg1_high_band_net(x[:, :, bandw:]),
72 | ],
73 | dim=2,
74 | )
75 |
76 | h = torch.cat([x, aux1], dim=1)
77 | aux2 = self.stg2_full_band_net(self.stg2_bridge(h))
78 |
79 | h = torch.cat([x, aux1, aux2], dim=1)
80 | h = self.stg3_full_band_net(self.stg3_bridge(h))
81 |
82 | mask = torch.sigmoid(self.out(h))
83 | mask = F.pad(
84 | input=mask,
85 | pad=(0, 0, 0, self.output_bin - mask.size()[2]),
86 | mode="replicate",
87 | )
88 |
89 | if self.training:
90 | aux1 = torch.sigmoid(self.aux1_out(aux1))
91 | aux1 = F.pad(
92 | input=aux1,
93 | pad=(0, 0, 0, self.output_bin - aux1.size()[2]),
94 | mode="replicate",
95 | )
96 | aux2 = torch.sigmoid(self.aux2_out(aux2))
97 | aux2 = F.pad(
98 | input=aux2,
99 | pad=(0, 0, 0, self.output_bin - aux2.size()[2]),
100 | mode="replicate",
101 | )
102 | return mask * mix, aux1 * mix, aux2 * mix
103 | else:
104 | if aggressiveness:
105 | mask[:, :, : aggressiveness["split_bin"]] = torch.pow(
106 | mask[:, :, : aggressiveness["split_bin"]],
107 | 1 + aggressiveness["value"] / 3,
108 | )
109 | mask[:, :, aggressiveness["split_bin"] :] = torch.pow(
110 | mask[:, :, aggressiveness["split_bin"] :],
111 | 1 + aggressiveness["value"],
112 | )
113 |
114 | return mask * mix
115 |
116 | def predict(self, x_mag, aggressiveness=None):
117 | h = self.forward(x_mag, aggressiveness)
118 |
119 | if self.offset > 0:
120 | h = h[:, :, :, self.offset : -self.offset]
121 | assert h.size()[3] > 0
122 |
123 | return h
124 |
--------------------------------------------------------------------------------
/infer/lib/uvr5_pack/utils.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import torch
3 | from tqdm import tqdm
4 |
5 |
6 | def make_padding(width, cropsize, offset):
7 | left = offset
8 | roi_size = cropsize - left * 2
9 | if roi_size == 0:
10 | roi_size = cropsize
11 | right = roi_size - (width % roi_size) + left
12 |
13 | return left, right, roi_size
14 |
15 |
16 | def inference(X_spec, device, model, aggressiveness, data):
17 | """
18 | data : dic configs
19 | """
20 |
21 | def _execute(
22 | X_mag_pad, roi_size, n_window, device, model, aggressiveness, is_half=True
23 | ):
24 | model.eval()
25 | with torch.no_grad():
26 | preds = []
27 |
28 | iterations = [n_window]
29 |
30 | total_iterations = sum(iterations)
31 | for i in tqdm(range(n_window)):
32 | start = i * roi_size
33 | X_mag_window = X_mag_pad[
34 | None, :, :, start : start + data["window_size"]
35 | ]
36 | X_mag_window = torch.from_numpy(X_mag_window)
37 | if is_half:
38 | X_mag_window = X_mag_window.half()
39 | X_mag_window = X_mag_window.to(device)
40 |
41 | pred = model.predict(X_mag_window, aggressiveness)
42 |
43 | pred = pred.detach().cpu().numpy()
44 | preds.append(pred[0])
45 |
46 | pred = np.concatenate(preds, axis=2)
47 | return pred
48 |
49 | def preprocess(X_spec):
50 | X_mag = np.abs(X_spec)
51 | X_phase = np.angle(X_spec)
52 |
53 | return X_mag, X_phase
54 |
55 | X_mag, X_phase = preprocess(X_spec)
56 |
57 | coef = X_mag.max()
58 | X_mag_pre = X_mag / coef
59 |
60 | n_frame = X_mag_pre.shape[2]
61 | pad_l, pad_r, roi_size = make_padding(n_frame, data["window_size"], model.offset)
62 | n_window = int(np.ceil(n_frame / roi_size))
63 |
64 | X_mag_pad = np.pad(X_mag_pre, ((0, 0), (0, 0), (pad_l, pad_r)), mode="constant")
65 |
66 | if list(model.state_dict().values())[0].dtype == torch.float16:
67 | is_half = True
68 | else:
69 | is_half = False
70 | pred = _execute(
71 | X_mag_pad, roi_size, n_window, device, model, aggressiveness, is_half
72 | )
73 | pred = pred[:, :, :n_frame]
74 |
75 | if data["tta"]:
76 | pad_l += roi_size // 2
77 | pad_r += roi_size // 2
78 | n_window += 1
79 |
80 | X_mag_pad = np.pad(X_mag_pre, ((0, 0), (0, 0), (pad_l, pad_r)), mode="constant")
81 |
82 | pred_tta = _execute(
83 | X_mag_pad, roi_size, n_window, device, model, aggressiveness, is_half
84 | )
85 | pred_tta = pred_tta[:, :, roi_size // 2 :]
86 | pred_tta = pred_tta[:, :, :n_frame]
87 |
88 | return (pred + pred_tta) * 0.5 * coef, X_mag, np.exp(1.0j * X_phase)
89 | else:
90 | return pred * coef, X_mag, np.exp(1.0j * X_phase)
91 |
--------------------------------------------------------------------------------
/infer/modules/gui/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | TorchGating is a PyTorch-based implementation of Spectral Gating
3 | ================================================
4 | Author: Asaf Zorea
5 |
6 | Contents
7 | --------
8 | torchgate imports all the functions from PyTorch, and in addition provides:
9 | TorchGating --- A PyTorch module that applies a spectral gate to an input signal
10 |
11 | """
12 |
13 | from .torchgate import TorchGate
14 |
--------------------------------------------------------------------------------
/infer/modules/gui/utils.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.types import Number
3 |
4 |
5 | @torch.no_grad()
6 | def amp_to_db(
7 | x: torch.Tensor, eps=torch.finfo(torch.float64).eps, top_db=40
8 | ) -> torch.Tensor:
9 | """
10 | Convert the input tensor from amplitude to decibel scale.
11 |
12 | Arguments:
13 | x {[torch.Tensor]} -- [Input tensor.]
14 |
15 | Keyword Arguments:
16 | eps {[float]} -- [Small value to avoid numerical instability.]
17 | (default: {torch.finfo(torch.float64).eps})
18 | top_db {[float]} -- [threshold the output at ``top_db`` below the peak]
19 | ` (default: {40})
20 |
21 | Returns:
22 | [torch.Tensor] -- [Output tensor in decibel scale.]
23 | """
24 | x_db = 20 * torch.log10(x.abs() + eps)
25 | return torch.max(x_db, (x_db.max(-1).values - top_db).unsqueeze(-1))
26 |
27 |
28 | @torch.no_grad()
29 | def temperature_sigmoid(x: torch.Tensor, x0: float, temp_coeff: float) -> torch.Tensor:
30 | """
31 | Apply a sigmoid function with temperature scaling.
32 |
33 | Arguments:
34 | x {[torch.Tensor]} -- [Input tensor.]
35 | x0 {[float]} -- [Parameter that controls the threshold of the sigmoid.]
36 | temp_coeff {[float]} -- [Parameter that controls the slope of the sigmoid.]
37 |
38 | Returns:
39 | [torch.Tensor] -- [Output tensor after applying the sigmoid with temperature scaling.]
40 | """
41 | return torch.sigmoid((x - x0) / temp_coeff)
42 |
43 |
44 | @torch.no_grad()
45 | def linspace(
46 | start: Number, stop: Number, num: int = 50, endpoint: bool = True, **kwargs
47 | ) -> torch.Tensor:
48 | """
49 | Generate a linearly spaced 1-D tensor.
50 |
51 | Arguments:
52 | start {[Number]} -- [The starting value of the sequence.]
53 | stop {[Number]} -- [The end value of the sequence, unless `endpoint` is set to False.
54 | In that case, the sequence consists of all but the last of ``num + 1``
55 | evenly spaced samples, so that `stop` is excluded. Note that the step
56 | size changes when `endpoint` is False.]
57 |
58 | Keyword Arguments:
59 | num {[int]} -- [Number of samples to generate. Default is 50. Must be non-negative.]
60 | endpoint {[bool]} -- [If True, `stop` is the last sample. Otherwise, it is not included.
61 | Default is True.]
62 | **kwargs -- [Additional arguments to be passed to the underlying PyTorch `linspace` function.]
63 |
64 | Returns:
65 | [torch.Tensor] -- [1-D tensor of `num` equally spaced samples from `start` to `stop`.]
66 | """
67 | if endpoint:
68 | return torch.linspace(start, stop, num, **kwargs)
69 | else:
70 | return torch.linspace(start, stop, num + 1, **kwargs)[:-1]
71 |
--------------------------------------------------------------------------------
/infer/modules/train/extract_f0_print.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import traceback
4 | from pathlib import Path
5 |
6 | from dotenv import load_dotenv
7 |
8 | now_dir = os.getcwd()
9 | sys.path.append(now_dir)
10 | load_dotenv()
11 | load_dotenv("sha256.env")
12 |
13 | now_dir = os.getcwd()
14 | sys.path.append(now_dir)
15 | import logging
16 |
17 | import numpy as np
18 |
19 | from infer.lib.audio import load_audio
20 |
21 | from rvc.f0 import Generator
22 |
23 | logging.getLogger("numba").setLevel(logging.WARNING)
24 | from multiprocessing import Process
25 |
26 | exp_dir = sys.argv[1]
27 | f = open("%s/extract_f0_feature.log" % exp_dir, "a+")
28 |
29 |
30 | def printt(strr):
31 | print(strr)
32 | f.write("%s\n" % strr)
33 | f.flush()
34 |
35 |
36 | n_p = int(sys.argv[2])
37 | f0method = sys.argv[3]
38 | device = sys.argv[4]
39 | is_half = sys.argv[5] == "True"
40 |
41 |
42 | class FeatureInput(object):
43 | def __init__(self, is_half: bool, device="cpu", samplerate=16000, hop_size=160):
44 | self.fs = samplerate
45 | self.hop = hop_size
46 |
47 | self.f0_bin = 256
48 | self.f0_max = 1100.0
49 | self.f0_min = 50.0
50 | self.f0_mel_min = 1127 * np.log(1 + self.f0_min / 700)
51 | self.f0_mel_max = 1127 * np.log(1 + self.f0_max / 700)
52 |
53 | self.f0_gen = Generator(
54 | Path(os.environ["rmvpe_root"]),
55 | is_half,
56 | 0,
57 | device,
58 | hop_size,
59 | samplerate,
60 | )
61 |
62 | def go(self, paths, f0_method):
63 | if len(paths) == 0:
64 | printt("no-f0-todo")
65 | else:
66 | printt("todo-f0-%s" % len(paths))
67 | n = max(len(paths) // 5, 1) # 每个进程最多打印5条
68 | for idx, (inp_path, opt_path1, opt_path2) in enumerate(paths):
69 | try:
70 | if idx % n == 0:
71 | printt("f0ing,now-%s,all-%s,-%s" % (idx, len(paths), inp_path))
72 | if (
73 | os.path.exists(opt_path1 + ".npy") == True
74 | and os.path.exists(opt_path2 + ".npy") == True
75 | ):
76 | continue
77 | x = load_audio(inp_path, self.fs)
78 | coarse_pit, feature_pit = self.f0_gen.calculate(
79 | x, x.shape[0] // self.hop, 0, f0_method, None
80 | )
81 | np.save(
82 | opt_path2,
83 | feature_pit,
84 | allow_pickle=False,
85 | ) # nsf
86 | np.save(
87 | opt_path1,
88 | coarse_pit,
89 | allow_pickle=False,
90 | ) # ori
91 | except:
92 | printt("f0fail-%s-%s-%s" % (idx, inp_path, traceback.format_exc()))
93 |
94 |
95 | if __name__ == "__main__":
96 | # exp_dir=r"E:\codes\py39\dataset\mi-test"
97 | # n_p=16
98 | # f = open("%s/log_extract_f0.log"%exp_dir, "w")
99 | printt(" ".join(sys.argv))
100 | featureInput = FeatureInput(is_half, device)
101 | paths = []
102 | inp_root = "%s/1_16k_wavs" % (exp_dir)
103 | opt_root1 = "%s/2a_f0" % (exp_dir)
104 | opt_root2 = "%s/2b-f0nsf" % (exp_dir)
105 |
106 | os.makedirs(opt_root1, exist_ok=True)
107 | os.makedirs(opt_root2, exist_ok=True)
108 | for name in sorted(list(os.listdir(inp_root))):
109 | inp_path = "%s/%s" % (inp_root, name)
110 | if "spec" in inp_path:
111 | continue
112 | opt_path1 = "%s/%s" % (opt_root1, name)
113 | opt_path2 = "%s/%s" % (opt_root2, name)
114 | paths.append([inp_path, opt_path1, opt_path2])
115 |
116 | ps = []
117 | for i in range(n_p):
118 | p = Process(
119 | target=featureInput.go,
120 | args=(
121 | paths[i::n_p],
122 | f0method,
123 | ),
124 | )
125 | ps.append(p)
126 | p.start()
127 | for i in range(n_p):
128 | ps[i].join()
129 |
--------------------------------------------------------------------------------
/infer/modules/train/extract_feature_print.py:
--------------------------------------------------------------------------------
1 | import os
2 | import sys
3 | import traceback
4 |
5 | now_dir = os.getcwd()
6 | sys.path.append(now_dir)
7 |
8 | from infer.lib.audio import load_audio
9 |
10 | os.environ["PYTORCH_ENABLE_MPS_FALLBACK"] = "1"
11 | os.environ["PYTORCH_MPS_HIGH_WATERMARK_RATIO"] = "0.0"
12 |
13 | device = sys.argv[1]
14 | n_part = int(sys.argv[2])
15 | i_part = int(sys.argv[3])
16 | if len(sys.argv) == 7:
17 | exp_dir = sys.argv[4]
18 | version = sys.argv[5]
19 | is_half = sys.argv[6].lower() == "true"
20 | else:
21 | i_gpu = sys.argv[4]
22 | exp_dir = sys.argv[5]
23 | os.environ["CUDA_VISIBLE_DEVICES"] = str(i_gpu)
24 | version = sys.argv[6]
25 | is_half = sys.argv[7].lower() == "true"
26 | import fairseq
27 | import numpy as np
28 | import torch
29 | import torch.nn.functional as F
30 |
31 | if "privateuseone" not in device:
32 | device = "cpu"
33 | if torch.cuda.is_available():
34 | device = "cuda"
35 | elif torch.backends.mps.is_available():
36 | device = "mps"
37 | else:
38 | import torch_directml
39 |
40 | device = torch_directml.device(torch_directml.default_device())
41 |
42 | def forward_dml(ctx, x, scale):
43 | ctx.scale = scale
44 | res = x.clone().detach()
45 | return res
46 |
47 | fairseq.modules.grad_multiply.GradMultiply.forward = forward_dml
48 |
49 | f = open("%s/extract_f0_feature.log" % exp_dir, "a+")
50 |
51 |
52 | def printt(strr):
53 | print(strr)
54 | f.write("%s\n" % strr)
55 | f.flush()
56 |
57 |
58 | printt(" ".join(sys.argv))
59 | model_path = "assets/hubert/hubert_base.pt"
60 |
61 | printt("exp_dir: " + exp_dir)
62 | wavPath = "%s/1_16k_wavs" % exp_dir
63 | outPath = (
64 | "%s/3_feature256" % exp_dir if version == "v1" else "%s/3_feature768" % exp_dir
65 | )
66 | os.makedirs(outPath, exist_ok=True)
67 |
68 |
69 | # wave must be 16k, hop_size=320
70 | def readwave(wav_path, normalize=False):
71 | wav, sr = load_audio(wav_path)
72 | assert sr == 16000
73 | feats = torch.from_numpy(wav).float()
74 | assert feats.dim() == 1, feats.dim()
75 | if normalize:
76 | with torch.no_grad():
77 | feats = F.layer_norm(feats, feats.shape)
78 | feats = feats.view(1, -1)
79 | return feats
80 |
81 |
82 | # HuBERT model
83 | printt("load model(s) from {}".format(model_path))
84 | # if hubert model is exist
85 | if os.access(model_path, os.F_OK) == False:
86 | printt(
87 | "Error: Extracting is shut down because %s does not exist, you may download it from https://huggingface.co/lj1995/VoiceConversionWebUI/tree/main"
88 | % model_path
89 | )
90 | exit(0)
91 | models, saved_cfg, task = fairseq.checkpoint_utils.load_model_ensemble_and_task(
92 | [model_path],
93 | suffix="",
94 | )
95 | model = models[0]
96 | model = model.to(device)
97 | printt("move model to %s" % device)
98 | if is_half:
99 | if device not in ["mps", "cpu"]:
100 | model = model.half()
101 | model.eval()
102 |
103 | todo = sorted(list(os.listdir(wavPath)))[i_part::n_part]
104 | n = max(1, len(todo) // 10) # 最多打印十条
105 | if len(todo) == 0:
106 | printt("no-feature-todo")
107 | else:
108 | printt("all-feature-%s" % len(todo))
109 | for idx, file in enumerate(todo):
110 | try:
111 | if file.endswith(".wav"):
112 | wav_path = "%s/%s" % (wavPath, file)
113 | out_path = "%s/%s" % (outPath, file.replace("wav", "npy"))
114 |
115 | if os.path.exists(out_path):
116 | continue
117 |
118 | feats = readwave(wav_path, normalize=saved_cfg.task.normalize)
119 | padding_mask = torch.BoolTensor(feats.shape).fill_(False)
120 | inputs = {
121 | "source": (
122 | feats.half().to(device)
123 | if is_half and device not in ["mps", "cpu"]
124 | else feats.to(device)
125 | ),
126 | "padding_mask": padding_mask.to(device),
127 | "output_layer": 9 if version == "v1" else 12, # layer 9
128 | }
129 | with torch.no_grad():
130 | logits = model.extract_features(**inputs)
131 | feats = (
132 | model.final_proj(logits[0]) if version == "v1" else logits[0]
133 | )
134 |
135 | feats = feats.squeeze(0).float().cpu().numpy()
136 | if np.isnan(feats).sum() == 0:
137 | np.save(out_path, feats, allow_pickle=False)
138 | else:
139 | printt("%s-contains nan" % file)
140 | if idx % n == 0:
141 | printt("now-%s,all-%s,%s,%s" % (len(todo), idx, file, feats.shape))
142 | except:
143 | printt(traceback.format_exc())
144 | printt("all-feature-done")
145 |
--------------------------------------------------------------------------------
/infer/modules/train/preprocess.py:
--------------------------------------------------------------------------------
1 | import multiprocessing
2 | import os
3 | import sys
4 |
5 | from scipy import signal
6 |
7 | now_dir = os.getcwd()
8 | sys.path.append(now_dir)
9 | print(*sys.argv[1:])
10 | inp_root = sys.argv[1]
11 | sr = int(sys.argv[2])
12 | n_p = int(sys.argv[3])
13 | exp_dir = sys.argv[4]
14 | noparallel = sys.argv[5] == "True"
15 | per = float(sys.argv[6])
16 | import os
17 | import traceback
18 |
19 | import numpy as np
20 |
21 | from infer.lib.audio import load_audio, float_np_array_to_wav_buf, save_audio
22 | from infer.lib.slicer2 import Slicer
23 |
24 | f = open("%s/preprocess.log" % exp_dir, "a+")
25 |
26 |
27 | def println(strr):
28 | print(strr)
29 | f.write("%s\n" % strr)
30 | f.flush()
31 |
32 |
33 | class PreProcess:
34 | def __init__(self, sr, exp_dir, per=3.7):
35 | self.slicer = Slicer(
36 | sr=sr,
37 | threshold=-42,
38 | min_length=1500,
39 | min_interval=400,
40 | hop_size=15,
41 | max_sil_kept=500,
42 | )
43 | self.sr = sr
44 | self.bh, self.ah = signal.butter(N=5, Wn=48, btype="high", fs=self.sr)
45 | self.per = per
46 | self.overlap = 0.3
47 | self.tail = self.per + self.overlap
48 | self.max = 0.9
49 | self.alpha = 0.75
50 | self.exp_dir = exp_dir
51 | self.gt_wavs_dir = "%s/0_gt_wavs" % exp_dir
52 | self.wavs16k_dir = "%s/1_16k_wavs" % exp_dir
53 | os.makedirs(self.exp_dir, exist_ok=True)
54 | os.makedirs(self.gt_wavs_dir, exist_ok=True)
55 | os.makedirs(self.wavs16k_dir, exist_ok=True)
56 |
57 | def norm_write(self, tmp_audio, idx0, idx1):
58 | tmp_max = np.abs(tmp_audio).max()
59 | if tmp_max > 2.5:
60 | print("%s-%s-%s-filtered" % (idx0, idx1, tmp_max))
61 | return
62 | tmp_audio = (tmp_audio / tmp_max * (self.max * self.alpha)) + (
63 | 1 - self.alpha
64 | ) * tmp_audio
65 | save_audio(
66 | "%s/%s_%s.wav" % (self.gt_wavs_dir, idx0, idx1),
67 | tmp_audio,
68 | self.sr,
69 | f32=True,
70 | )
71 | with open("%s/%s_%s.wav" % (self.wavs16k_dir, idx0, idx1), "wb") as f:
72 | f.write(
73 | float_np_array_to_wav_buf(
74 | load_audio(
75 | float_np_array_to_wav_buf(tmp_audio, self.sr, f32=True),
76 | sr=16000,
77 | format="wav",
78 | ),
79 | 16000,
80 | True,
81 | ).getbuffer()
82 | )
83 |
84 | def pipeline(self, path, idx0):
85 | try:
86 | audio = load_audio(path, self.sr)
87 | # zero phased digital filter cause pre-ringing noise...
88 | # audio = signal.filtfilt(self.bh, self.ah, audio)
89 | audio = signal.lfilter(self.bh, self.ah, audio)
90 |
91 | idx1 = 0
92 | for audio in self.slicer.slice(audio):
93 | i = 0
94 | while 1:
95 | start = int(self.sr * (self.per - self.overlap) * i)
96 | i += 1
97 | if len(audio[start:]) > self.tail * self.sr:
98 | tmp_audio = audio[start : start + int(self.per * self.sr)]
99 | self.norm_write(tmp_audio, idx0, idx1)
100 | idx1 += 1
101 | else:
102 | tmp_audio = audio[start:]
103 | idx1 += 1
104 | break
105 | self.norm_write(tmp_audio, idx0, idx1)
106 | println("%s\t-> Success" % path)
107 | except:
108 | println("%s\t-> %s" % (path, traceback.format_exc()))
109 |
110 | def pipeline_mp(self, infos):
111 | for path, idx0 in infos:
112 | self.pipeline(path, idx0)
113 |
114 | def pipeline_mp_inp_dir(self, inp_root, n_p):
115 | try:
116 | infos = [
117 | ("%s/%s" % (inp_root, name), idx)
118 | for idx, name in enumerate(sorted(list(os.listdir(inp_root))))
119 | ]
120 | if noparallel:
121 | for i in range(n_p):
122 | self.pipeline_mp(infos[i::n_p])
123 | else:
124 | ps = []
125 | for i in range(n_p):
126 | p = multiprocessing.Process(
127 | target=self.pipeline_mp, args=(infos[i::n_p],)
128 | )
129 | ps.append(p)
130 | p.start()
131 | for i in range(n_p):
132 | ps[i].join()
133 | except:
134 | println("Fail. %s" % traceback.format_exc())
135 |
136 |
137 | def preprocess_trainset(inp_root, sr, n_p, exp_dir, per):
138 | pp = PreProcess(sr, exp_dir, per)
139 | println("start preprocess")
140 | pp.pipeline_mp_inp_dir(inp_root, n_p)
141 | println("end preprocess")
142 |
143 |
144 | if __name__ == "__main__":
145 | preprocess_trainset(inp_root, sr, n_p, exp_dir, per)
146 |
--------------------------------------------------------------------------------
/infer/modules/uvr5/modules.py:
--------------------------------------------------------------------------------
1 | import os
2 | import traceback
3 | import logging
4 |
5 | logger = logging.getLogger(__name__)
6 |
7 | from infer.lib.audio import resample_audio, get_audio_properties
8 | import torch
9 |
10 | from configs import Config
11 | from infer.modules.uvr5.mdxnet import MDXNetDereverb
12 | from infer.modules.uvr5.vr import AudioPre
13 |
14 | config = Config()
15 |
16 |
17 | def uvr(model_name, inp_root, save_root_vocal, paths, save_root_ins, agg, format0):
18 | infos = []
19 | try:
20 | inp_root = inp_root.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
21 | save_root_vocal = (
22 | save_root_vocal.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
23 | )
24 | save_root_ins = (
25 | save_root_ins.strip(" ").strip('"').strip("\n").strip('"').strip(" ")
26 | )
27 | if model_name == "onnx_dereverb_By_FoxJoy":
28 | pre_fun = MDXNetDereverb(15, config.device)
29 | else:
30 | pre_fun = AudioPre(
31 | agg=int(agg),
32 | model_path=os.path.join(
33 | os.getenv("weight_uvr5_root"), model_name + ".pth"
34 | ),
35 | device=config.device,
36 | is_half=config.is_half,
37 | )
38 | if inp_root != "":
39 | paths = [os.path.join(inp_root, name) for name in os.listdir(inp_root)]
40 | else:
41 | paths = [path.name for path in paths]
42 | for path in paths:
43 | inp_path = os.path.join(inp_root, path)
44 | need_reformat = 1
45 | done = 0
46 | try:
47 | channels, rate = get_audio_properties(inp_path)
48 |
49 | # Check the audio stream's properties
50 | if channels == 2 and rate == 44100:
51 | pre_fun._path_audio_(
52 | inp_path, save_root_ins, save_root_vocal, format0
53 | )
54 | need_reformat = 0
55 | done = 1
56 | except Exception as e:
57 | need_reformat = 1
58 | logger.warning(f"Exception {e} occured. Will reformat")
59 | if need_reformat == 1:
60 | tmp_path = "%s/%s.reformatted.wav" % (
61 | os.path.join(os.environ["TEMP"]),
62 | os.path.basename(inp_path),
63 | )
64 | resample_audio(inp_path, tmp_path, "pcm_s16le", "s16", 44100, "stereo")
65 | try: # Remove the original file
66 | os.remove(inp_path)
67 | except Exception as e:
68 | print(f"Failed to remove the original file: {e}")
69 | inp_path = tmp_path
70 | try:
71 | if done == 0:
72 | pre_fun._path_audio_(
73 | inp_path, save_root_ins, save_root_vocal, format0
74 | )
75 | infos.append("%s->Success" % (os.path.basename(inp_path)))
76 | yield "\n".join(infos)
77 | except:
78 | infos.append(
79 | "%s->%s" % (os.path.basename(inp_path), traceback.format_exc())
80 | )
81 | yield "\n".join(infos)
82 | except:
83 | infos.append(traceback.format_exc())
84 | yield "\n".join(infos)
85 | finally:
86 | try:
87 | if model_name == "onnx_dereverb_By_FoxJoy":
88 | del pre_fun.pred.model
89 | del pre_fun.pred.model_
90 | else:
91 | del pre_fun.model
92 | del pre_fun
93 | except:
94 | traceback.print_exc()
95 | if torch.cuda.is_available():
96 | torch.cuda.empty_cache()
97 | logger.info("Executed torch.cuda.empty_cache()")
98 | elif torch.backends.mps.is_available():
99 | torch.mps.empty_cache()
100 | logger.info("Executed torch.mps.empty_cache()")
101 | yield "\n".join(infos)
102 |
--------------------------------------------------------------------------------
/infer/modules/vc/__init__.py:
--------------------------------------------------------------------------------
1 | from .pipeline import Pipeline
2 | from .modules import VC
3 | from .utils import get_index_path_from_model, load_hubert
4 | from .info import show_info
5 | from .hash import model_hash_ckpt, hash_id, hash_similarity
6 |
--------------------------------------------------------------------------------
/infer/modules/vc/info.py:
--------------------------------------------------------------------------------
1 | import traceback
2 | from i18n.i18n import I18nAuto
3 | from datetime import datetime
4 | import torch
5 |
6 | from .hash import model_hash_ckpt, hash_id, hash_similarity
7 |
8 | i18n = I18nAuto()
9 |
10 |
11 | def show_model_info(cpt, show_long_id=False):
12 | try:
13 | h = model_hash_ckpt(cpt)
14 | id = hash_id(h)
15 | idread = cpt.get("id", "None")
16 | hread = cpt.get("hash", "None")
17 | if id != idread:
18 | id += (
19 | "("
20 | + i18n("Actually calculated")
21 | + "), "
22 | + idread
23 | + "("
24 | + i18n("Read from model")
25 | + ")"
26 | )
27 | sim = hash_similarity(h, hread)
28 | if not isinstance(sim, str):
29 | sim = "%.2f%%" % (sim * 100)
30 | if not show_long_id:
31 | h = i18n("Hidden")
32 | if h != hread:
33 | h = i18n("Similarity") + " " + sim + " -> " + h
34 | elif h != hread:
35 | h = (
36 | i18n("Similarity")
37 | + " "
38 | + sim
39 | + " -> "
40 | + h
41 | + "("
42 | + i18n("Actually calculated")
43 | + "), "
44 | + hread
45 | + "("
46 | + i18n("Read from model")
47 | + ")"
48 | )
49 | txt = f"""{i18n("Model name")}: %s
50 | {i18n("Sealing date")}: %s
51 | {i18n("Model Author")}: %s
52 | {i18n("Information")}: %s
53 | {i18n("Sampling rate")}: %s
54 | {i18n("Pitch guidance (f0)")}: %s
55 | {i18n("Version")}: %s
56 | {i18n("ID(short)")}: %s
57 | {i18n("ID(long)")}: %s""" % (
58 | cpt.get("name", i18n("Unknown")),
59 | datetime.fromtimestamp(float(cpt.get("timestamp", 0))),
60 | cpt.get("author", i18n("Unknown")),
61 | cpt.get("info", i18n("None")),
62 | cpt.get("sr", i18n("Unknown")),
63 | i18n("Exist") if cpt.get("f0", 0) == 1 else i18n("Not exist"),
64 | cpt.get("version", i18n("None")),
65 | id,
66 | h,
67 | )
68 | except:
69 | txt = traceback.format_exc()
70 |
71 | return txt
72 |
73 |
74 | def show_info(path):
75 | try:
76 | if hasattr(path, "name"):
77 | path = path.name
78 | a = torch.load(path, map_location="cpu")
79 | txt = show_model_info(a, show_long_id=True)
80 | del a
81 | except:
82 | txt = traceback.format_exc()
83 |
84 | return txt
85 |
--------------------------------------------------------------------------------
/infer/modules/vc/lgdsng.npz:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/infer/modules/vc/lgdsng.npz
--------------------------------------------------------------------------------
/infer/modules/vc/utils.py:
--------------------------------------------------------------------------------
1 | import os, pathlib
2 |
3 | from fairseq import checkpoint_utils
4 |
5 |
6 | def get_index_path_from_model(sid):
7 | return next(
8 | (
9 | f
10 | for f in [
11 | str(pathlib.Path(root, name))
12 | for path in [os.getenv("outside_index_root"), os.getenv("index_root")]
13 | for root, _, files in os.walk(path, topdown=False)
14 | for name in files
15 | if name.endswith(".index") and "trained" not in name
16 | ]
17 | if sid.split(".")[0] in f
18 | ),
19 | "",
20 | )
21 |
22 |
23 | def load_hubert(device, is_half):
24 | models, _, _ = checkpoint_utils.load_model_ensemble_and_task(
25 | ["assets/hubert/hubert_base.pt"],
26 | suffix="",
27 | )
28 | hubert_model = models[0]
29 | hubert_model = hubert_model.to(device)
30 | if is_half:
31 | hubert_model = hubert_model.half()
32 | else:
33 | hubert_model = hubert_model.float()
34 | return hubert_model.eval()
35 |
--------------------------------------------------------------------------------
/logs/mute/0_gt_wavs/mute32k.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/0_gt_wavs/mute32k.wav
--------------------------------------------------------------------------------
/logs/mute/0_gt_wavs/mute40k.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/0_gt_wavs/mute40k.wav
--------------------------------------------------------------------------------
/logs/mute/0_gt_wavs/mute48k.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/0_gt_wavs/mute48k.wav
--------------------------------------------------------------------------------
/logs/mute/1_16k_wavs/mute.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/1_16k_wavs/mute.wav
--------------------------------------------------------------------------------
/logs/mute/2a_f0/mute.wav.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/2a_f0/mute.wav.npy
--------------------------------------------------------------------------------
/logs/mute/2b-f0nsf/mute.wav.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/2b-f0nsf/mute.wav.npy
--------------------------------------------------------------------------------
/logs/mute/3_feature256/mute.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/3_feature256/mute.npy
--------------------------------------------------------------------------------
/logs/mute/3_feature768/mute.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/logs/mute/3_feature768/mute.npy
--------------------------------------------------------------------------------
/requirements/amd.txt:
--------------------------------------------------------------------------------
1 | tensorflow-rocm
2 | joblib>=1.1.0
3 | numba==0.56.4
4 | numpy==1.23.5
5 | scipy
6 | librosa>=0.10.2
7 | llvmlite==0.39.0
8 | fairseq==0.12.2
9 | faiss-cpu==1.7.3
10 | gradio
11 | Cython
12 | pydub>=0.25.1
13 | tensorboardX
14 | Jinja2>=3.1.2
15 | json5
16 | Markdown
17 | matplotlib>=3.7.0
18 | matplotlib-inline>=0.1.3
19 | praat-parselmouth>=0.4.2
20 | Pillow>=9.1.1
21 | resampy>=0.4.2
22 | scikit-learn
23 | tensorboard
24 | tqdm>=4.63.1
25 | tornado>=6.1
26 | Werkzeug>=2.2.3
27 | uc-micro-py>=1.0.1
28 | sympy>=1.11.1
29 | tabulate>=0.8.10
30 | PyYAML>=6.0
31 | pyasn1>=0.4.8
32 | pyasn1-modules>=0.2.8
33 | fsspec>=2022.11.0
34 | absl-py>=1.2.0
35 | audioread
36 | uvicorn>=0.21.1
37 | colorama>=0.4.5
38 | pyworld==0.3.2
39 | httpx
40 | onnxruntime
41 | onnxruntime-gpu
42 | torchcrepe>=0.0.23
43 | fastapi
44 | python-dotenv>=1.0.0
45 | av
46 | torchfcpe
47 | pybase16384
48 |
--------------------------------------------------------------------------------
/requirements/dml.txt:
--------------------------------------------------------------------------------
1 | joblib>=1.1.0
2 | numba==0.56.4
3 | numpy==1.23.5
4 | scipy
5 | librosa>=0.10.2
6 | llvmlite==0.39.0
7 | fairseq==0.12.2
8 | faiss-cpu==1.7.3
9 | gradio
10 | Cython
11 | pydub>=0.25.1
12 | tensorboardX
13 | Jinja2>=3.1.2
14 | json5
15 | Markdown
16 | matplotlib>=3.7.0
17 | matplotlib-inline>=0.1.3
18 | praat-parselmouth>=0.4.2
19 | Pillow>=9.1.1
20 | resampy>=0.4.2
21 | scikit-learn
22 | tensorboard
23 | tqdm>=4.63.1
24 | tornado>=6.1
25 | Werkzeug>=2.2.3
26 | uc-micro-py>=1.0.1
27 | sympy>=1.11.1
28 | tabulate>=0.8.10
29 | PyYAML>=6.0
30 | pyasn1>=0.4.8
31 | pyasn1-modules>=0.2.8
32 | fsspec>=2022.11.0
33 | absl-py>=1.2.0
34 | audioread
35 | uvicorn>=0.21.1
36 | colorama>=0.4.5
37 | pyworld==0.3.2
38 | httpx
39 | onnxruntime-directml
40 | torchcrepe>=0.0.23
41 | fastapi
42 | python-dotenv>=1.0.0
43 | av
44 | torchfcpe
45 | pybase16384
46 |
--------------------------------------------------------------------------------
/requirements/gui-dml.txt:
--------------------------------------------------------------------------------
1 | #1.Install torch from pytorch.org:
2 | #torch 2.0 with cuda 11.8
3 | #pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
4 | #torch 1.11.0 with cuda 11.3
5 | #pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu113
6 | einops
7 | fairseq
8 | flask
9 | flask_cors
10 | gin
11 | gin_config
12 | librosa
13 | local_attention
14 | matplotlib
15 | praat-parselmouth
16 | pyworld
17 | PyYAML
18 | resampy
19 | scikit_learn
20 | scipy
21 | tensorboard
22 | tqdm
23 | wave
24 | FreeSimpleGUI
25 | sounddevice
26 | gradio
27 | noisereduce
28 | onnxruntime-directml
29 | torchfcpe
--------------------------------------------------------------------------------
/requirements/gui.txt:
--------------------------------------------------------------------------------
1 | #1.Install torch from pytorch.org:
2 | #torch 2.0 with cuda 11.8
3 | #pip3 install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118
4 | #torch 1.11.0 with cuda 11.3
5 | #pip install torch==1.11.0+cu113 torchvision==0.12.0+cu113 torchaudio==0.11.0 --extra-index-url https://download.pytorch.org/whl/cu113
6 | einops
7 | fairseq
8 | flask
9 | flask_cors
10 | gin
11 | gin_config
12 | librosa
13 | local_attention
14 | matplotlib
15 | praat-parselmouth
16 | pyworld
17 | PyYAML
18 | resampy
19 | scikit_learn
20 | scipy
21 | tensorboard
22 | tqdm
23 | wave
24 | FreeSimpleGUI
25 | sounddevice
26 | gradio
27 | noisereduce
28 | torchfcpe
29 |
--------------------------------------------------------------------------------
/requirements/ipex.txt:
--------------------------------------------------------------------------------
1 | torch==2.0.1a0
2 | intel_extension_for_pytorch==2.0.110+xpu
3 | torchvision==0.15.2a0
4 | https://github.com/Disty0/Retrieval-based-Voice-Conversion-WebUI/releases/download/torchaudio_wheels_for_ipex/torchaudio-2.0.2+31de77d-cp310-cp310-linux_x86_64.whl
5 | --extra-index-url https://pytorch-extension.intel.com/release-whl/stable/xpu/us/
6 | joblib>=1.1.0
7 | numba==0.56.4
8 | numpy==1.23.5
9 | scipy
10 | librosa>=0.10.2
11 | llvmlite==0.39.0
12 | fairseq==0.12.2
13 | faiss-cpu==1.7.3
14 | gradio
15 | Cython
16 | pydub>=0.25.1
17 | tensorboardX
18 | Jinja2>=3.1.2
19 | json5
20 | Markdown
21 | matplotlib>=3.7.0
22 | matplotlib-inline>=0.1.3
23 | praat-parselmouth>=0.4.2
24 | Pillow>=9.1.1
25 | resampy>=0.4.2
26 | scikit-learn
27 | tensorboard
28 | tqdm>=4.63.1
29 | tornado>=6.1
30 | Werkzeug>=2.2.3
31 | uc-micro-py>=1.0.1
32 | sympy>=1.11.1
33 | tabulate>=0.8.10
34 | PyYAML>=6.0
35 | pyasn1>=0.4.8
36 | pyasn1-modules>=0.2.8
37 | fsspec>=2022.11.0
38 | absl-py>=1.2.0
39 | audioread
40 | uvicorn>=0.21.1
41 | colorama>=0.4.5
42 | pyworld==0.3.2
43 | httpx
44 | onnxruntime; sys_platform == 'darwin'
45 | onnxruntime-gpu; sys_platform != 'darwin'
46 | torchcrepe>=0.0.23
47 | fastapi
48 | python-dotenv>=1.0.0
49 | av
50 | FreeSimpleGUI
51 | sounddevice
52 | torchfcpe
53 | pybase16384
54 |
--------------------------------------------------------------------------------
/requirements/main.txt:
--------------------------------------------------------------------------------
1 | joblib>=1.1.0
2 | numba
3 | numpy==1.23.5
4 | scipy
5 | librosa>=0.10.2
6 | llvmlite
7 | fairseq
8 | faiss-cpu
9 | gradio
10 | Cython
11 | pydub>=0.25.1
12 | tensorboardX
13 | Jinja2>=3.1.2
14 | json5
15 | Markdown
16 | matplotlib>=3.7.0
17 | matplotlib-inline>=0.1.3
18 | praat-parselmouth>=0.4.2
19 | Pillow>=9.1.1
20 | resampy>=0.4.2
21 | scikit-learn
22 | tensorboard
23 | tqdm>=4.63.1
24 | tornado>=6.1
25 | Werkzeug>=2.2.3
26 | uc-micro-py>=1.0.1
27 | sympy>=1.11.1
28 | tabulate>=0.8.10
29 | PyYAML>=6.0
30 | pyasn1>=0.4.8
31 | pyasn1-modules>=0.2.8
32 | fsspec>=2022.11.0
33 | absl-py>=1.2.0
34 | audioread
35 | uvicorn>=0.21.1
36 | colorama>=0.4.5
37 | pyworld==0.3.2
38 | httpx
39 | onnxruntime; sys_platform == 'darwin'
40 | onnxruntime-gpu; sys_platform != 'darwin'
41 | torchcrepe>=0.0.23
42 | fastapi
43 | torchfcpe
44 | python-dotenv>=1.0.0
45 | av
46 | pybase16384
47 |
--------------------------------------------------------------------------------
/requirements/py311.txt:
--------------------------------------------------------------------------------
1 | joblib>=1.1.0
2 | numba
3 | numpy
4 | scipy
5 | librosa>=0.10.2
6 | llvmlite
7 | fairseq @ git+https://github.com/One-sixth/fairseq.git
8 | faiss-cpu
9 | gradio
10 | Cython
11 | pydub>=0.25.1
12 | tensorboardX
13 | Jinja2>=3.1.2
14 | json5
15 | Markdown
16 | matplotlib>=3.7.0
17 | matplotlib-inline>=0.1.3
18 | praat-parselmouth>=0.4.2
19 | Pillow>=9.1.1
20 | resampy>=0.4.2
21 | scikit-learn
22 | tensorboard
23 | tqdm>=4.63.1
24 | tornado>=6.1
25 | Werkzeug>=2.2.3
26 | uc-micro-py>=1.0.1
27 | sympy>=1.11.1
28 | tabulate>=0.8.10
29 | PyYAML>=6.0
30 | pyasn1>=0.4.8
31 | pyasn1-modules>=0.2.8
32 | fsspec>=2022.11.0
33 | absl-py>=1.2.0
34 | audioread
35 | uvicorn>=0.21.1
36 | colorama>=0.4.5
37 | pyworld==0.3.2
38 | httpx
39 | onnxruntime; sys_platform == 'darwin'
40 | onnxruntime-gpu; sys_platform != 'darwin'
41 | torchcrepe>=0.0.23
42 | fastapi
43 | torchfcpe
44 | python-dotenv>=1.0.0
45 | av
46 | pybase16384
47 |
--------------------------------------------------------------------------------
/run.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | set -fa
4 |
5 | # Check if Python is installed
6 | if ! command -v python; then
7 | echo "Python not found. Please install Python using your package manager or via PyEnv."
8 | exit 1
9 | fi
10 |
11 | requirements_file="requirements/main.txt"
12 | venv_path=".venv"
13 |
14 | if [[ ! -d "${venv_path}" ]]; then
15 | echo "Creating venv..."
16 |
17 | python -m venv "${venv_path}"
18 | source "${venv_path}/bin/activate"
19 |
20 | # Check if required packages are up-to-date
21 | pip install --upgrade -r "${requirements_file}"
22 | fi
23 | echo "Activating venv..."
24 | source "${venv_path}/bin/activate"
25 |
26 | # Run the main script
27 | python web.py --pycmd python
28 |
--------------------------------------------------------------------------------
/rvc/__init__.py:
--------------------------------------------------------------------------------
1 | from . import ipex
2 | import sys
3 |
4 | del sys.modules["rvc.ipex"]
5 |
--------------------------------------------------------------------------------
/rvc/f0/__init__.py:
--------------------------------------------------------------------------------
1 | from .gen import Generator
2 |
--------------------------------------------------------------------------------
/rvc/f0/crepe.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional, Union
2 |
3 | import numpy as np
4 | import torch
5 | import torchcrepe
6 |
7 | from .f0 import F0Predictor
8 |
9 |
10 | class CRePE(F0Predictor):
11 | def __init__(
12 | self,
13 | hop_length=512,
14 | f0_min=50,
15 | f0_max=1100,
16 | sampling_rate=44100,
17 | device="cpu",
18 | ):
19 | if "privateuseone" in str(device):
20 | device = "cpu"
21 | super().__init__(
22 | hop_length,
23 | f0_min,
24 | f0_max,
25 | sampling_rate,
26 | device,
27 | )
28 |
29 | def compute_f0(
30 | self,
31 | wav: np.ndarray,
32 | p_len: Optional[int] = None,
33 | filter_radius: Optional[Union[int, float]] = None,
34 | ):
35 | if p_len is None:
36 | p_len = wav.shape[0] // self.hop_length
37 | if not torch.is_tensor(wav):
38 | wav = torch.from_numpy(wav)
39 | # Pick a batch size that doesn't cause memory errors on your gpu
40 | batch_size = 512
41 | # Compute pitch using device 'device'
42 | f0, pd = torchcrepe.predict(
43 | wav.float().to(self.device).unsqueeze(dim=0),
44 | self.sampling_rate,
45 | self.hop_length,
46 | self.f0_min,
47 | self.f0_max,
48 | batch_size=batch_size,
49 | device=self.device,
50 | return_periodicity=True,
51 | )
52 | pd = torchcrepe.filter.median(pd, 3)
53 | f0 = torchcrepe.filter.mean(f0, 3)
54 | f0[pd < 0.1] = 0
55 | f0 = f0[0].cpu().numpy()
56 | return self._interpolate_f0(self._resize_f0(f0, p_len))[0]
57 |
--------------------------------------------------------------------------------
/rvc/f0/dio.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional, Union
2 |
3 | import numpy as np
4 | import pyworld
5 |
6 | from .f0 import F0Predictor
7 |
8 |
9 | class Dio(F0Predictor):
10 | def __init__(self, hop_length=512, f0_min=50, f0_max=1100, sampling_rate=44100):
11 | super().__init__(hop_length, f0_min, f0_max, sampling_rate)
12 |
13 | def compute_f0(
14 | self,
15 | wav: np.ndarray,
16 | p_len: Optional[int] = None,
17 | filter_radius: Optional[Union[int, float]] = None,
18 | ):
19 | if p_len is None:
20 | p_len = wav.shape[0] // self.hop_length
21 | f0, t = pyworld.dio(
22 | wav.astype(np.double),
23 | fs=self.sampling_rate,
24 | f0_floor=self.f0_min,
25 | f0_ceil=self.f0_max,
26 | frame_period=1000 * self.hop_length / self.sampling_rate,
27 | )
28 | f0 = pyworld.stonemask(wav.astype(np.double), f0, t, self.sampling_rate)
29 | for index, pitch in enumerate(f0):
30 | f0[index] = round(pitch, 1)
31 | return self._interpolate_f0(self._resize_f0(f0, p_len))[0]
32 |
--------------------------------------------------------------------------------
/rvc/f0/e2e.py:
--------------------------------------------------------------------------------
1 | from typing import Tuple
2 |
3 | import torch.nn as nn
4 |
5 | from .deepunet import DeepUnet
6 |
7 |
8 | class E2E(nn.Module):
9 | def __init__(
10 | self,
11 | n_blocks: int,
12 | n_gru: int,
13 | kernel_size: Tuple[int, int],
14 | en_de_layers=5,
15 | inter_layers=4,
16 | in_channels=1,
17 | en_out_channels=16,
18 | ):
19 | super(E2E, self).__init__()
20 |
21 | self.unet = DeepUnet(
22 | kernel_size,
23 | n_blocks,
24 | en_de_layers,
25 | inter_layers,
26 | in_channels,
27 | en_out_channels,
28 | )
29 | self.cnn = nn.Conv2d(en_out_channels, 3, (3, 3), padding=(1, 1))
30 | if n_gru:
31 | self.fc = nn.Sequential(
32 | self.BiGRU(3 * 128, 256, n_gru),
33 | nn.Linear(512, 360),
34 | nn.Dropout(0.25),
35 | nn.Sigmoid(),
36 | )
37 | else:
38 | self.fc = nn.Sequential(
39 | nn.Linear(3 * nn.N_MELS, nn.N_CLASS),
40 | nn.Dropout(0.25),
41 | nn.Sigmoid(),
42 | )
43 |
44 | def forward(self, mel):
45 | mel = mel.transpose(-1, -2).unsqueeze(1)
46 | x = self.cnn(self.unet(mel)).transpose(1, 2).flatten(-2)
47 | x = self.fc(x)
48 | return x
49 |
50 | class BiGRU(nn.Module):
51 | def __init__(
52 | self,
53 | input_features: int,
54 | hidden_features: int,
55 | num_layers: int,
56 | ):
57 | super().__init__()
58 | self.gru = nn.GRU(
59 | input_features,
60 | hidden_features,
61 | num_layers=num_layers,
62 | batch_first=True,
63 | bidirectional=True,
64 | )
65 |
66 | def forward(self, x):
67 | return self.gru(x)[0]
68 |
--------------------------------------------------------------------------------
/rvc/f0/f0.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, Union
2 |
3 | import torch
4 | import numpy as np
5 |
6 |
7 | class F0Predictor(object):
8 | def __init__(
9 | self,
10 | hop_length=512,
11 | f0_min=50,
12 | f0_max=1100,
13 | sampling_rate=44100,
14 | device: Optional[str] = None,
15 | ):
16 | self.hop_length = hop_length
17 | self.f0_min = f0_min
18 | self.f0_max = f0_max
19 | self.sampling_rate = sampling_rate
20 | if device is None:
21 | device = "cuda:0" if torch.cuda.is_available() else "cpu"
22 | self.device = device
23 |
24 | def compute_f0(
25 | self,
26 | wav: np.ndarray,
27 | p_len: Optional[int] = None,
28 | filter_radius: Optional[Union[int, float]] = None,
29 | ): ...
30 |
31 | def _interpolate_f0(self, f0: np.ndarray):
32 | """
33 | 对F0进行插值处理
34 | """
35 |
36 | data = np.reshape(f0, (f0.size, 1))
37 |
38 | vuv_vector = np.zeros((data.size, 1), dtype=np.float32)
39 | vuv_vector[data > 0.0] = 1.0
40 | vuv_vector[data <= 0.0] = 0.0
41 |
42 | ip_data = data
43 |
44 | frame_number = data.size
45 | last_value = 0.0
46 | for i in range(frame_number):
47 | if data[i] <= 0.0:
48 | j = i + 1
49 | for j in range(i + 1, frame_number):
50 | if data[j] > 0.0:
51 | break
52 | if j < frame_number - 1:
53 | if last_value > 0.0:
54 | step = (data[j] - data[i - 1]) / float(j - i)
55 | for k in range(i, j):
56 | ip_data[k] = data[i - 1] + step * (k - i + 1)
57 | else:
58 | for k in range(i, j):
59 | ip_data[k] = data[j]
60 | else:
61 | for k in range(i, frame_number):
62 | ip_data[k] = last_value
63 | else:
64 | ip_data[i] = data[i] # 这里可能存在一个没有必要的拷贝
65 | last_value = data[i]
66 |
67 | return ip_data[:, 0], vuv_vector[:, 0]
68 |
69 | def _resize_f0(self, x: np.ndarray, target_len: int):
70 | source = np.array(x)
71 | source[source < 0.001] = np.nan
72 | target = np.interp(
73 | np.arange(0, len(source) * target_len, len(source)) / target_len,
74 | np.arange(0, len(source)),
75 | source,
76 | )
77 | res = np.nan_to_num(target)
78 | return res
79 |
--------------------------------------------------------------------------------
/rvc/f0/fcpe.py:
--------------------------------------------------------------------------------
1 | from typing import Optional, Union
2 |
3 | import numpy as np
4 | import torch
5 |
6 | from .f0 import F0Predictor
7 |
8 |
9 | class FCPE(F0Predictor):
10 | def __init__(
11 | self,
12 | hop_length=512,
13 | f0_min=50,
14 | f0_max=1100,
15 | sampling_rate=44100,
16 | device="cpu",
17 | ):
18 | super().__init__(
19 | hop_length,
20 | f0_min,
21 | f0_max,
22 | sampling_rate,
23 | device,
24 | )
25 |
26 | from torchfcpe import (
27 | spawn_bundled_infer_model,
28 | ) # must be imported at here, or it will cause fairseq crash on training
29 |
30 | self.model = spawn_bundled_infer_model(self.device)
31 |
32 | def compute_f0(
33 | self,
34 | wav: np.ndarray,
35 | p_len: Optional[int] = None,
36 | filter_radius: Optional[Union[int, float]] = 0.006,
37 | ):
38 | if p_len is None:
39 | p_len = wav.shape[0] // self.hop_length
40 | if not torch.is_tensor(wav):
41 | wav = torch.from_numpy(wav)
42 | f0 = (
43 | self.model.infer(
44 | wav.float().to(self.device).unsqueeze(0),
45 | sr=self.sampling_rate,
46 | decoder_mode="local_argmax",
47 | threshold=filter_radius,
48 | )
49 | .squeeze()
50 | .cpu()
51 | .numpy()
52 | )
53 | return self._interpolate_f0(self._resize_f0(f0, p_len))[0]
54 |
--------------------------------------------------------------------------------
/rvc/f0/harvest.py:
--------------------------------------------------------------------------------
1 | from typing import Any, Optional, Union
2 |
3 | import numpy as np
4 | import pyworld
5 | from scipy import signal
6 |
7 | from .f0 import F0Predictor
8 |
9 |
10 | class Harvest(F0Predictor):
11 | def __init__(self, hop_length=512, f0_min=50, f0_max=1100, sampling_rate=44100):
12 | super().__init__(hop_length, f0_min, f0_max, sampling_rate)
13 |
14 | def compute_f0(
15 | self,
16 | wav: np.ndarray,
17 | p_len: Optional[int] = None,
18 | filter_radius: Optional[Union[int, float]] = None,
19 | ):
20 | if p_len is None:
21 | p_len = wav.shape[0] // self.hop_length
22 | f0, t = pyworld.harvest(
23 | wav.astype(np.double),
24 | fs=self.sampling_rate,
25 | f0_ceil=self.f0_max,
26 | f0_floor=self.f0_min,
27 | frame_period=1000 * self.hop_length / self.sampling_rate,
28 | )
29 | f0 = pyworld.stonemask(wav.astype(np.double), f0, t, self.sampling_rate)
30 | if filter_radius is not None and filter_radius > 2:
31 | f0 = signal.medfilt(f0, filter_radius)
32 | return self._interpolate_f0(self._resize_f0(f0, p_len))[0]
33 |
--------------------------------------------------------------------------------
/rvc/f0/mel.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import torch
4 | import numpy as np
5 | from librosa.filters import mel
6 |
7 | from .stft import STFT
8 |
9 |
10 | class MelSpectrogram(torch.nn.Module):
11 | def __init__(
12 | self,
13 | is_half: bool,
14 | n_mel_channels: int,
15 | sampling_rate: int,
16 | win_length: int,
17 | hop_length: int,
18 | n_fft: Optional[int] = None,
19 | mel_fmin: int = 0,
20 | mel_fmax: int = None,
21 | clamp: float = 1e-5,
22 | device=torch.device("cpu"),
23 | ):
24 | super().__init__()
25 | if n_fft is None:
26 | n_fft = win_length
27 | mel_basis = mel(
28 | sr=sampling_rate,
29 | n_fft=n_fft,
30 | n_mels=n_mel_channels,
31 | fmin=mel_fmin,
32 | fmax=mel_fmax,
33 | htk=True,
34 | )
35 | mel_basis = torch.from_numpy(mel_basis).float()
36 | self.register_buffer("mel_basis", mel_basis)
37 | self.n_fft = n_fft
38 | self.hop_length = hop_length
39 | self.win_length = win_length
40 | self.clamp = clamp
41 | self.is_half = is_half
42 |
43 | self.stft = STFT(
44 | filter_length=n_fft,
45 | hop_length=hop_length,
46 | win_length=win_length,
47 | window="hann",
48 | use_torch_stft="privateuseone" not in str(device),
49 | ).to(device)
50 |
51 | def forward(
52 | self,
53 | audio: torch.Tensor,
54 | keyshift=0,
55 | speed=1,
56 | center=True,
57 | ):
58 | factor = 2 ** (keyshift / 12)
59 | win_length_new = int(np.round(self.win_length * factor))
60 | magnitude = self.stft(audio, keyshift, speed, center)
61 | if keyshift != 0:
62 | size = self.n_fft // 2 + 1
63 | resize = magnitude.size(1)
64 | if resize < size:
65 | magnitude = torch.nn.functional.pad(magnitude, (0, 0, 0, size - resize))
66 | magnitude = magnitude[:, :size, :] * self.win_length / win_length_new
67 | mel_output = torch.matmul(self.mel_basis, magnitude)
68 | if self.is_half:
69 | mel_output = mel_output.half()
70 | log_mel_spec = torch.log(torch.clamp(mel_output, min=self.clamp))
71 | return log_mel_spec
72 |
--------------------------------------------------------------------------------
/rvc/f0/models.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 |
4 | def get_rmvpe(
5 | model_path="assets/rmvpe/rmvpe.pt", device=torch.device("cpu"), is_half=False
6 | ):
7 | from rvc.f0.e2e import E2E
8 |
9 | model = E2E(4, 1, (2, 2))
10 | ckpt = torch.load(model_path, map_location=device, weights_only=True)
11 | model.load_state_dict(ckpt)
12 | del ckpt
13 | model.eval()
14 | if is_half:
15 | model = model.half()
16 | model = model.to(device)
17 | return model
18 |
--------------------------------------------------------------------------------
/rvc/f0/pm.py:
--------------------------------------------------------------------------------
1 | from typing import Optional
2 |
3 | import numpy as np
4 | import parselmouth
5 |
6 | from .f0 import F0Predictor
7 |
8 |
9 | class PM(F0Predictor):
10 | def __init__(self, hop_length=512, f0_min=50, f0_max=1100, sampling_rate=44100):
11 | super().__init__(hop_length, f0_min, f0_max, sampling_rate)
12 |
13 | def compute_f0(
14 | self,
15 | wav: np.ndarray,
16 | p_len: Optional[int] = None,
17 | filter_radius: Optional[int] = None,
18 | ):
19 | x = wav
20 | if p_len is None:
21 | p_len = x.shape[0] // self.hop_length
22 | else:
23 | assert abs(p_len - x.shape[0] // self.hop_length) < 4, "pad length error"
24 | time_step = self.hop_length / self.sampling_rate * 1000
25 | f0 = (
26 | parselmouth.Sound(x, self.sampling_rate)
27 | .to_pitch_ac(
28 | time_step=time_step / 1000,
29 | voicing_threshold=0.6,
30 | pitch_floor=self.f0_min,
31 | pitch_ceiling=self.f0_max,
32 | )
33 | .selected_array["frequency"]
34 | )
35 |
36 | pad_size = (p_len - len(f0) + 1) // 2
37 | if pad_size > 0 or p_len - len(f0) - pad_size > 0:
38 | f0 = np.pad(f0, [[pad_size, p_len - len(f0) - pad_size]], mode="constant")
39 | return self._interpolate_f0(f0)[0]
40 |
--------------------------------------------------------------------------------
/rvc/ipex/__init__.py:
--------------------------------------------------------------------------------
1 | try:
2 | import torch
3 |
4 | if torch.xpu.is_available():
5 | from .init import ipex_init
6 |
7 | ipex_init()
8 | from .gradscaler import gradscaler_init
9 | except Exception: # pylint: disable=broad-exception-caught
10 | pass
11 |
--------------------------------------------------------------------------------
/rvc/jit/__init__.py:
--------------------------------------------------------------------------------
1 | from .jit import load_inputs, get_jit_model, export_jit_model, save_pickle
2 |
--------------------------------------------------------------------------------
/rvc/jit/jit.py:
--------------------------------------------------------------------------------
1 | import pickle
2 | from io import BytesIO
3 | from collections import OrderedDict
4 | import os
5 |
6 | import torch
7 |
8 |
9 | def load_pickle(path: str):
10 | with open(path, "rb") as f:
11 | return pickle.load(f)
12 |
13 |
14 | def save_pickle(ckpt: dict, save_path: str):
15 | with open(save_path, "wb") as f:
16 | pickle.dump(ckpt, f)
17 |
18 |
19 | def load_inputs(path: torch.serialization.FILE_LIKE, device: str, is_half=False):
20 | parm = torch.load(path, map_location=torch.device("cpu"))
21 | for key in parm.keys():
22 | parm[key] = parm[key].to(device)
23 | if is_half and parm[key].dtype == torch.float32:
24 | parm[key] = parm[key].half()
25 | elif not is_half and parm[key].dtype == torch.float16:
26 | parm[key] = parm[key].float()
27 | return parm
28 |
29 |
30 | def export_jit_model(
31 | model: torch.nn.Module,
32 | mode: str = "trace",
33 | inputs: dict = None,
34 | device=torch.device("cpu"),
35 | is_half: bool = False,
36 | ) -> dict:
37 | model = model.half() if is_half else model.float()
38 | model.eval()
39 | if mode == "trace":
40 | assert inputs is not None
41 | model_jit = torch.jit.trace(model, example_kwarg_inputs=inputs)
42 | elif mode == "script":
43 | model_jit = torch.jit.script(model)
44 | model_jit.to(device)
45 | model_jit = model_jit.half() if is_half else model_jit.float()
46 | buffer = BytesIO()
47 | # model_jit=model_jit.cpu()
48 | torch.jit.save(model_jit, buffer)
49 | del model_jit
50 | cpt = OrderedDict()
51 | cpt["model"] = buffer.getvalue()
52 | cpt["is_half"] = is_half
53 | return cpt
54 |
55 |
56 | def get_jit_model(model_path: str, is_half: bool, device: str, exporter):
57 | jit_model_path = model_path.rstrip(".pth")
58 | jit_model_path += ".half.jit" if is_half else ".jit"
59 | ckpt = None
60 |
61 | if os.path.exists(jit_model_path):
62 | ckpt = load_pickle(jit_model_path)
63 | model_device = ckpt["device"]
64 | if model_device != str(device):
65 | del ckpt
66 | ckpt = None
67 |
68 | if ckpt is None:
69 | ckpt = exporter(
70 | model_path=model_path,
71 | mode="script",
72 | inputs_path=None,
73 | save_path=jit_model_path,
74 | device=device,
75 | is_half=is_half,
76 | )
77 |
78 | return ckpt
79 |
--------------------------------------------------------------------------------
/rvc/layers/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fumiama/Retrieval-based-Voice-Conversion-WebUI/e1aeb16630158cd6b0b9db8d6d27fe1ad869e42d/rvc/layers/__init__.py
--------------------------------------------------------------------------------
/rvc/layers/utils.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional, Tuple, Iterator
2 |
3 | import torch
4 |
5 |
6 | def call_weight_data_normal_if_Conv(m: torch.nn.Module):
7 | classname = m.__class__.__name__
8 | if classname.find("Conv") != -1:
9 | mean = 0.0
10 | std = 0.01
11 | m.weight.data.normal_(mean, std)
12 |
13 |
14 | def get_padding(kernel_size: int, dilation=1) -> int:
15 | return int((kernel_size * dilation - dilation) / 2)
16 |
17 |
18 | def slice_on_last_dim(
19 | x: torch.Tensor,
20 | start_indices: List[int],
21 | segment_size=4,
22 | ) -> torch.Tensor:
23 | new_shape = [*x.shape]
24 | new_shape[-1] = segment_size
25 | ret = torch.empty(new_shape, device=x.device)
26 | for i in range(x.size(0)):
27 | idx_str = start_indices[i]
28 | idx_end = idx_str + segment_size
29 | ret[i, ..., :] = x[i, ..., idx_str:idx_end]
30 | return ret
31 |
32 |
33 | def rand_slice_segments_on_last_dim(
34 | x: torch.Tensor,
35 | x_lengths: int = None,
36 | segment_size=4,
37 | ) -> Tuple[torch.Tensor, List[int]]:
38 | b, _, t = x.size()
39 | if x_lengths is None:
40 | x_lengths = t
41 | ids_str_max = x_lengths - segment_size + 1
42 | ids_str = (torch.rand([b]).to(device=x.device) * ids_str_max).to(dtype=torch.long)
43 | ret = slice_on_last_dim(x, ids_str, segment_size)
44 | return ret, ids_str
45 |
46 |
47 | @torch.jit.script
48 | def activate_add_tanh_sigmoid_multiply(
49 | input_a: torch.Tensor, input_b: torch.Tensor, n_channels: int
50 | ) -> torch.Tensor:
51 | in_act = input_a + input_b
52 | t_act = torch.tanh(in_act[:, :n_channels, :])
53 | s_act = torch.sigmoid(in_act[:, n_channels:, :])
54 | acts = t_act * s_act
55 | return acts
56 |
57 |
58 | def sequence_mask(
59 | length: torch.Tensor,
60 | max_length: Optional[int] = None,
61 | ) -> torch.BoolTensor:
62 | if max_length is None:
63 | max_length = int(length.max())
64 | x = torch.arange(max_length, dtype=length.dtype, device=length.device)
65 | return x.unsqueeze(0) < length.unsqueeze(1)
66 |
67 |
68 | def total_grad_norm(
69 | parameters: Iterator[torch.nn.Parameter],
70 | norm_type: float = 2.0,
71 | ) -> float:
72 | norm_type = float(norm_type)
73 | total_norm = 0.0
74 |
75 | for p in parameters:
76 | if p.grad is None:
77 | continue
78 | param_norm = p.grad.data.norm(norm_type)
79 | total_norm += float(param_norm.item()) ** norm_type
80 | total_norm = total_norm ** (1.0 / norm_type)
81 |
82 | return total_norm
83 |
--------------------------------------------------------------------------------
/rvc/onnx/__init__.py:
--------------------------------------------------------------------------------
1 | from .infer import RVC
2 | from .exporter import export_onnx
3 |
--------------------------------------------------------------------------------
/rvc/onnx/exporter.py:
--------------------------------------------------------------------------------
1 | import torch
2 |
3 | from .synthesizer import SynthesizerTrnMsNSFsid
4 |
5 |
6 | def export_onnx(from_cpkt_pth: str, to_onnx_pth: str) -> str:
7 | cpt = torch.load(from_cpkt_pth, map_location="cpu")
8 | cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0]
9 | vec_channels = 256 if cpt.get("version", "v1") == "v1" else 768
10 |
11 | test_phone = torch.rand(1, 200, vec_channels) # hidden unit
12 | test_phone_lengths = torch.tensor([200]).long() # hidden unit 长度(貌似没啥用)
13 | test_pitch = torch.randint(size=(1, 200), low=5, high=255) # 基频(单位赫兹)
14 | test_pitchf = torch.rand(1, 200) # nsf基频
15 | test_ds = torch.LongTensor([0]) # 说话人ID
16 | test_rnd = torch.rand(1, 192, 200) # 噪声(加入随机因子)
17 |
18 | device = "cpu" # 导出时设备(不影响使用模型)
19 |
20 | net_g = SynthesizerTrnMsNSFsid(
21 | *cpt["config"], encoder_dim=vec_channels
22 | ) # fp32导出(C++要支持fp16必须手动将内存重新排列所以暂时不用fp16)
23 | net_g.load_state_dict(cpt["weight"], strict=False)
24 | input_names = ["phone", "phone_lengths", "pitch", "pitchf", "ds", "rnd"]
25 | output_names = [
26 | "audio",
27 | ]
28 | # net_g.construct_spkmixmap() #多角色混合轨道导出
29 | torch.onnx.export(
30 | net_g,
31 | (
32 | test_phone.to(device),
33 | test_phone_lengths.to(device),
34 | test_pitch.to(device),
35 | test_pitchf.to(device),
36 | test_ds.to(device),
37 | test_rnd.to(device),
38 | ),
39 | to_onnx_pth,
40 | dynamic_axes={
41 | "phone": [1],
42 | "pitch": [1],
43 | "pitchf": [1],
44 | "rnd": [2],
45 | },
46 | do_constant_folding=False,
47 | opset_version=17,
48 | verbose=False,
49 | input_names=input_names,
50 | output_names=output_names,
51 | )
52 | return "Finished"
53 |
--------------------------------------------------------------------------------
/rvc/onnx/infer.py:
--------------------------------------------------------------------------------
1 | import typing
2 | import os
3 |
4 | import librosa
5 | import numpy as np
6 | import onnxruntime
7 |
8 | from rvc.f0 import Generator
9 |
10 |
11 | class Model:
12 | def __init__(
13 | self,
14 | path: typing.Union[str, bytes, os.PathLike],
15 | device: typing.Literal["cpu", "cuda", "dml"] = "cpu",
16 | ):
17 | if device == "cpu":
18 | providers = ["CPUExecutionProvider"]
19 | elif device == "cuda":
20 | providers = ["CUDAExecutionProvider", "CPUExecutionProvider"]
21 | elif device == "dml":
22 | providers = ["DmlExecutionProvider"]
23 | else:
24 | raise RuntimeError("Unsportted Device")
25 | self.model = onnxruntime.InferenceSession(path, providers=providers)
26 |
27 |
28 | class ContentVec(Model):
29 | def __init__(
30 | self,
31 | vec_path: typing.Union[str, bytes, os.PathLike],
32 | device: typing.Literal["cpu", "cuda", "dml"] = "cpu",
33 | ):
34 | super().__init__(vec_path, device)
35 |
36 | def __call__(self, wav: np.ndarray[typing.Any, np.dtype]):
37 | return self.forward(wav)
38 |
39 | def forward(self, wav: np.ndarray[typing.Any, np.dtype]):
40 | if wav.ndim == 2: # double channels
41 | wav = wav.mean(-1)
42 | assert wav.ndim == 1, wav.ndim
43 | wav = np.expand_dims(np.expand_dims(wav, 0), 0)
44 | onnx_input = {self.model.get_inputs()[0].name: wav}
45 | logits = self.model.run(None, onnx_input)[0]
46 | return logits.transpose(0, 2, 1)
47 |
48 |
49 | class RVC(Model):
50 | def __init__(
51 | self,
52 | model_path: typing.Union[str, bytes, os.PathLike],
53 | hop_len=512,
54 | model_sr=40000,
55 | vec_path: typing.Union[str, bytes, os.PathLike] = "vec-768-layer-12.onnx",
56 | device: typing.Literal["cpu", "cuda", "dml"] = "cpu",
57 | ):
58 | super().__init__(model_path, device)
59 | self.vec_model = ContentVec(vec_path, device)
60 | self.hop_len = hop_len
61 | self.f0_gen = Generator(None, False, 0, window=hop_len, sr=model_sr)
62 |
63 | def infer(
64 | self,
65 | wav: np.ndarray[typing.Any, np.dtype],
66 | wav_sr: int,
67 | sid: int = 0,
68 | f0_method="dio",
69 | f0_up_key=0,
70 | ) -> np.ndarray[typing.Any, np.dtype[np.int16]]:
71 | org_length = len(wav)
72 | if org_length / wav_sr > 50.0:
73 | raise RuntimeError("wav max length exceeded")
74 |
75 | hubert = self.vec_model(librosa.resample(wav, orig_sr=wav_sr, target_sr=16000))
76 | hubert = np.repeat(hubert, 2, axis=2).transpose(0, 2, 1).astype(np.float32)
77 | hubert_length = hubert.shape[1]
78 |
79 | pitch, pitchf = self.f0_gen.calculate(
80 | wav, hubert_length, f0_up_key, f0_method, None
81 | )
82 | pitch = pitch.astype(np.int64)
83 |
84 | pitchf = pitchf.reshape(1, len(pitchf)).astype(np.float32)
85 | pitch = pitch.reshape(1, len(pitch))
86 | ds = np.array([sid]).astype(np.int64)
87 |
88 | rnd = np.random.randn(1, 192, hubert_length).astype(np.float32)
89 | hubert_length = np.array([hubert_length]).astype(np.int64)
90 |
91 | out_wav = self.forward(hubert, hubert_length, pitch, pitchf, ds, rnd).squeeze()
92 |
93 | out_wav = np.pad(out_wav, (0, 2 * self.hop_len), "constant")
94 |
95 | return out_wav[0:org_length]
96 |
97 | def forward(
98 | self,
99 | hubert: np.ndarray[typing.Any, np.dtype[np.float32]],
100 | hubert_length: int,
101 | pitch: np.ndarray[typing.Any, np.dtype[np.int64]],
102 | pitchf: np.ndarray[typing.Any, np.dtype[np.float32]],
103 | ds: np.ndarray[typing.Any, np.dtype[np.int64]],
104 | rnd: np.ndarray[typing.Any, np.dtype[np.float32]],
105 | ) -> np.ndarray[typing.Any, np.dtype[np.int16]]:
106 | onnx_input = {
107 | self.model.get_inputs()[0].name: hubert,
108 | self.model.get_inputs()[1].name: hubert_length,
109 | self.model.get_inputs()[2].name: pitch,
110 | self.model.get_inputs()[3].name: pitchf,
111 | self.model.get_inputs()[4].name: ds,
112 | self.model.get_inputs()[5].name: rnd,
113 | }
114 | return (self.model.run(None, onnx_input)[0] * 32767).astype(np.int16)
115 |
--------------------------------------------------------------------------------
/rvc/onnx/synthesizer.py:
--------------------------------------------------------------------------------
1 | from typing import List, Optional, Union
2 |
3 | import torch
4 |
5 | from rvc.layers.synthesizers import SynthesizerTrnMsNSFsid as SynthesizerBase
6 |
7 |
8 | class SynthesizerTrnMsNSFsid(SynthesizerBase):
9 | def __init__(
10 | self,
11 | spec_channels: int,
12 | segment_size: int,
13 | inter_channels: int,
14 | hidden_channels: int,
15 | filter_channels: int,
16 | n_heads: int,
17 | n_layers: int,
18 | kernel_size: int,
19 | p_dropout: int,
20 | resblock: str,
21 | resblock_kernel_sizes: List[int],
22 | resblock_dilation_sizes: List[List[int]],
23 | upsample_rates: List[int],
24 | upsample_initial_channel: int,
25 | upsample_kernel_sizes: List[int],
26 | spk_embed_dim: int,
27 | gin_channels: int,
28 | sr: Optional[Union[str, int]],
29 | encoder_dim: int,
30 | ):
31 | super().__init__(
32 | spec_channels,
33 | segment_size,
34 | inter_channels,
35 | hidden_channels,
36 | filter_channels,
37 | n_heads,
38 | n_layers,
39 | kernel_size,
40 | p_dropout,
41 | resblock,
42 | resblock_kernel_sizes,
43 | resblock_dilation_sizes,
44 | upsample_rates,
45 | upsample_initial_channel,
46 | upsample_kernel_sizes,
47 | spk_embed_dim,
48 | gin_channels,
49 | sr,
50 | encoder_dim,
51 | True,
52 | )
53 | self.speaker_map = None
54 |
55 | def remove_weight_norm(self):
56 | self.dec.remove_weight_norm()
57 | self.flow.remove_weight_norm()
58 | self.enc_q.remove_weight_norm()
59 |
60 | def construct_spkmixmap(self):
61 | self.speaker_map = torch.zeros((self.n_speaker, 1, 1, self.gin_channels))
62 | for i in range(self.n_speaker):
63 | self.speaker_map[i] = self.emb_g(torch.LongTensor([[i]]))
64 | self.speaker_map = self.speaker_map.unsqueeze(0)
65 |
66 | def forward(self, phone, phone_lengths, pitch, nsff0, g, rnd, max_len=None):
67 | if self.speaker_map is not None: # [N, S] * [S, B, 1, H]
68 | g = g.reshape((g.shape[0], g.shape[1], 1, 1, 1)) # [N, S, B, 1, 1]
69 | g = g * self.speaker_map # [N, S, B, 1, H]
70 | g = torch.sum(g, dim=1) # [N, 1, B, 1, H]
71 | g = g.transpose(0, -1).transpose(0, -2).squeeze(0) # [B, H, N]
72 | else:
73 | g = g.unsqueeze(0)
74 | g = self.emb_g(g).transpose(1, 2)
75 |
76 | m_p, logs_p, x_mask = self.enc_p(phone, pitch, phone_lengths)
77 | z_p = (m_p + torch.exp(logs_p) * rnd) * x_mask
78 | z = self.flow(z_p, x_mask, g=g, reverse=True)
79 | o = self.dec((z * x_mask)[:, :, :max_len], nsff0, g=g)
80 | return o
81 |
--------------------------------------------------------------------------------
/rvc/synthesizer.py:
--------------------------------------------------------------------------------
1 | from collections import OrderedDict
2 |
3 | import torch
4 |
5 | from .layers.synthesizers import SynthesizerTrnMsNSFsid
6 | from .jit import load_inputs, export_jit_model, save_pickle
7 |
8 |
9 | def get_synthesizer(cpt: OrderedDict, device=torch.device("cpu")):
10 | cpt["config"][-3] = cpt["weight"]["emb_g.weight"].shape[0]
11 | if_f0 = cpt.get("f0", 1)
12 | version = cpt.get("version", "v1")
13 | if version == "v1":
14 | encoder_dim = 256
15 | elif version == "v2":
16 | encoder_dim = 768
17 | net_g = SynthesizerTrnMsNSFsid(
18 | *cpt["config"],
19 | encoder_dim=encoder_dim,
20 | use_f0=if_f0 == 1,
21 | )
22 | del net_g.enc_q
23 | net_g.load_state_dict(cpt["weight"], strict=False)
24 | net_g = net_g.float()
25 | net_g.eval().to(device)
26 | net_g.remove_weight_norm()
27 | return net_g, cpt
28 |
29 |
30 | def load_synthesizer(
31 | pth_path: torch.serialization.FILE_LIKE, device=torch.device("cpu")
32 | ):
33 | return get_synthesizer(
34 | torch.load(pth_path, map_location=torch.device("cpu"), weights_only=True),
35 | device,
36 | )
37 |
38 |
39 | def synthesizer_jit_export(
40 | model_path: str,
41 | mode: str = "script",
42 | inputs_path: str = None,
43 | save_path: str = None,
44 | device=torch.device("cpu"),
45 | is_half=False,
46 | ):
47 | if not save_path:
48 | save_path = model_path.rstrip(".pth")
49 | save_path += ".half.jit" if is_half else ".jit"
50 | if "cuda" in str(device) and ":" not in str(device):
51 | device = torch.device("cuda:0")
52 | from rvc.synthesizer import load_synthesizer
53 |
54 | model, cpt = load_synthesizer(model_path, device)
55 | assert isinstance(cpt, dict)
56 | model.forward = model.infer
57 | inputs = None
58 | if mode == "trace":
59 | inputs = load_inputs(inputs_path, device, is_half)
60 | ckpt = export_jit_model(model, mode, inputs, device, is_half)
61 | cpt.pop("weight")
62 | cpt["model"] = ckpt["model"]
63 | cpt["device"] = device
64 | save_pickle(cpt, save_path)
65 | return cpt
66 |
--------------------------------------------------------------------------------
/sha256.env:
--------------------------------------------------------------------------------
1 | sha256_hubert_base_pt = f54b40fd2802423a5643779c4861af1e9ee9c1564dc9d32f54f20b5ffba7db96
2 | sha256_rmvpe_pt = 6d62215f4306e3ca278246188607209f09af3dc77ed4232efdd069798c4ec193
3 | sha256_rmvpe_onnx = 5370e71ac80af8b4b7c793d27efd51fd8bf962de3a7ede0766dac0befa3660fd
4 |
5 | sha256_v1_D32k_pth = 2ab20645829460fdad0d3c44254f1ab53c32cae50c22a66c926ae5aa30abda6f
6 | sha256_v1_D40k_pth = 547f66dbbcd9023b9051ed244d12ab043ba8a4e854b154cc28761ac7c002909b
7 | sha256_v1_D48k_pth = 8cc013fa60ed9c3f902f5bd99f48c7e3b9352d763d4d3cd6bc241c37b0bfd9ad
8 | sha256_v1_G32k_pth = 81817645cde7ed2e2d83f23ef883f33dda564924b497e84d792743912eca4c23
9 | sha256_v1_G40k_pth = e428573bda1124b0ae0ae843fd8dcded6027d3993444790b3e9b0100938b2113
10 | sha256_v1_G48k_pth = 3862a67ea6313e8ffefc05cee6bee656ef3e089442e9ecf4a6618d60721f3e95
11 | sha256_v1_f0D32k_pth = 294db3087236e2c75260d6179056791c9231245daf5d0485545d9e54c4057c77
12 | sha256_v1_f0D40k_pth = 7d4f5a441594b470d67579958b2fd4c6b992852ded28ff9e72eda67abcebe423
13 | sha256_v1_f0D48k_pth = 1b84c8bf347ad1e539c842e8f2a4c36ecd9e7fb23c16041189e4877e9b07925c
14 | sha256_v1_f0G32k_pth = 285f524bf48bb692c76ad7bd0bc654c12bd9e5edeb784dddf7f61a789a608574
15 | sha256_v1_f0G40k_pth = 9115654aeef1995f7dd3c6fc4140bebbef0ca9760bed798105a2380a34299831
16 | sha256_v1_f0G48k_pth = 78bc9cab27e34bcfc194f93029374d871d8b3e663ddedea32a9709e894cc8fe8
17 |
18 | sha256_v2_D32k_pth = d8043378cc6619083d385f5a045de09b83fb3bf8de45c433ca863b71723ac3ca
19 | sha256_v2_D40k_pth = 471378e894e7191f89a94eda8288c5947b16bbe0b10c3f1f17efdb7a1d998242
20 | sha256_v2_D48k_pth = db01094a93c09868a278e03dafe8bb781bfcc1a5ba8df168c948bf9168c84d82
21 | sha256_v2_G32k_pth = 869b26a47f75168d6126f64ac39e6de5247017a8658cfd68aca600f7323efb9f
22 | sha256_v2_G40k_pth = a3843da7fde33db1dab176146c70d6c2df06eafe9457f4e3aa10024e9c6a4b69
23 | sha256_v2_G48k_pth = 2e2b1581a436d07a76b10b9d38765f64aa02836dc65c7dee1ce4140c11ea158b
24 | sha256_v2_f0D32k_pth = bd7134e7793674c85474d5145d2d982e3c5d8124fc7bb6c20f710ed65808fa8a
25 | sha256_v2_f0D40k_pth = 6b6ab091e70801b28e3f41f335f2fc5f3f35c75b39ae2628d419644ec2b0fa09
26 | sha256_v2_f0D48k_pth = 2269b73c7a4cf34da09aea99274dabf99b2ddb8a42cbfb065fb3c0aa9a2fc748
27 | sha256_v2_f0G32k_pth = 2332611297b8d88c7436de8f17ef5f07a2119353e962cd93cda5806d59a1133d
28 | sha256_v2_f0G40k_pth = 3b2c44035e782c4b14ddc0bede9e2f4a724d025cd073f736d4f43708453adfcb
29 | sha256_v2_f0G48k_pth = b5d51f589cc3632d4eae36a315b4179397695042edc01d15312e1bddc2b764a4
30 |
31 | sha256_uvr5_HP2-人声vocals+非人声instrumentals_pth = 39796caa5db18d7f9382d8ac997ac967bfd85f7761014bb807d2543cc844ef05
32 | sha256_uvr5_HP2_all_vocals_pth = 39796caa5db18d7f9382d8ac997ac967bfd85f7761014bb807d2543cc844ef05
33 | sha256_uvr5_HP3_all_vocals_pth = 45e6b65199e781b4a6542002699be9f19cd3d1cb7d1558bc2bfbcd84674dfe28
34 | sha256_uvr5_HP5-主旋律人声vocals+其他instrumentals_pth = 5908891829634926119720241e8573d97cbeb8277110a7512bdb0bd7563258ee
35 | sha256_uvr5_HP5_only_main_vocal_pth = 5908891829634926119720241e8573d97cbeb8277110a7512bdb0bd7563258ee
36 | sha256_uvr5_VR-DeEchoAggressive_pth = 8c8fd1582f9aabc363e47af62ddb88df6cae7e064cae75bbf041a067a5e0aee2
37 | sha256_uvr5_VR-DeEchoDeReverb_pth = 01376dd2a571bf3cb9cced680732726d2d732609d09216a610b0d110f133febe
38 | sha256_uvr5_VR-DeEchoNormal_pth = 56aba59db3bcdd14a14464e62f3129698ecdea62eee0f003b9360923eb3ac79e
39 | sha256_uvr5_vocals_onnx = 233bb5c6aaa365e568659a0a81211746fa881f8f47f82d9e864fce1f7692db80
40 |
--------------------------------------------------------------------------------
/tools/checksum/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "crypto/sha256"
5 | "encoding/hex"
6 | "fmt"
7 | "io"
8 | "os"
9 | )
10 |
11 | func main() {
12 | var buf [32]byte
13 | h := sha256.New()
14 | lst := make([]any, 0, 64)
15 | for _, fname := range files {
16 | f, err := os.Open("assets/" + fname)
17 | if err != nil {
18 | panic(err)
19 | }
20 | _, err = io.Copy(h, f)
21 | if err != nil {
22 | panic(err)
23 | }
24 | s := hex.EncodeToString(h.Sum(buf[:0]))
25 | fmt.Println("sha256 of", fname, "=", s)
26 | lst = append(lst, s)
27 | h.Reset()
28 | f.Close()
29 | }
30 | f, err := os.Create("sha256.env")
31 | if err != nil {
32 | panic(err)
33 | }
34 | _, err = fmt.Fprintf(f, envtmpl, lst...)
35 | if err != nil {
36 | panic(err)
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tools/checksum/tmpl.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | var files = [...]string{
4 | "hubert/hubert_base.pt",
5 | "rmvpe/rmvpe.pt",
6 | "rmvpe/rmvpe.onnx",
7 |
8 | "pretrained/D32k.pth",
9 | "pretrained/D40k.pth",
10 | "pretrained/D48k.pth",
11 | "pretrained/G32k.pth",
12 | "pretrained/G40k.pth",
13 | "pretrained/G48k.pth",
14 | "pretrained/f0D32k.pth",
15 | "pretrained/f0D40k.pth",
16 | "pretrained/f0D48k.pth",
17 | "pretrained/f0G32k.pth",
18 | "pretrained/f0G40k.pth",
19 | "pretrained/f0G48k.pth",
20 |
21 | "pretrained_v2/D32k.pth",
22 | "pretrained_v2/D40k.pth",
23 | "pretrained_v2/D48k.pth",
24 | "pretrained_v2/G32k.pth",
25 | "pretrained_v2/G40k.pth",
26 | "pretrained_v2/G48k.pth",
27 | "pretrained_v2/f0D32k.pth",
28 | "pretrained_v2/f0D40k.pth",
29 | "pretrained_v2/f0D48k.pth",
30 | "pretrained_v2/f0G32k.pth",
31 | "pretrained_v2/f0G40k.pth",
32 | "pretrained_v2/f0G48k.pth",
33 |
34 | "uvr5_weights/HP2-人声vocals+非人声instrumentals.pth",
35 | "uvr5_weights/HP2_all_vocals.pth",
36 | "uvr5_weights/HP3_all_vocals.pth",
37 | "uvr5_weights/HP5-主旋律人声vocals+其他instrumentals.pth",
38 | "uvr5_weights/HP5_only_main_vocal.pth",
39 | "uvr5_weights/VR-DeEchoAggressive.pth",
40 | "uvr5_weights/VR-DeEchoDeReverb.pth",
41 | "uvr5_weights/VR-DeEchoNormal.pth",
42 | "uvr5_weights/onnx_dereverb_By_FoxJoy/vocals.onnx",
43 | }
44 |
45 | const envtmpl = `sha256_hubert_base_pt = %s
46 | sha256_rmvpe_pt = %s
47 | sha256_rmvpe_onnx = %s
48 |
49 | sha256_v1_D32k_pth = %s
50 | sha256_v1_D40k_pth = %s
51 | sha256_v1_D48k_pth = %s
52 | sha256_v1_G32k_pth = %s
53 | sha256_v1_G40k_pth = %s
54 | sha256_v1_G48k_pth = %s
55 | sha256_v1_f0D32k_pth = %s
56 | sha256_v1_f0D40k_pth = %s
57 | sha256_v1_f0D48k_pth = %s
58 | sha256_v1_f0G32k_pth = %s
59 | sha256_v1_f0G40k_pth = %s
60 | sha256_v1_f0G48k_pth = %s
61 |
62 | sha256_v2_D32k_pth = %s
63 | sha256_v2_D40k_pth = %s
64 | sha256_v2_D48k_pth = %s
65 | sha256_v2_G32k_pth = %s
66 | sha256_v2_G40k_pth = %s
67 | sha256_v2_G48k_pth = %s
68 | sha256_v2_f0D32k_pth = %s
69 | sha256_v2_f0D40k_pth = %s
70 | sha256_v2_f0D48k_pth = %s
71 | sha256_v2_f0G32k_pth = %s
72 | sha256_v2_f0G40k_pth = %s
73 | sha256_v2_f0G48k_pth = %s
74 |
75 | sha256_uvr5_HP2-人声vocals+非人声instrumentals_pth = %s
76 | sha256_uvr5_HP2_all_vocals_pth = %s
77 | sha256_uvr5_HP3_all_vocals_pth = %s
78 | sha256_uvr5_HP5-主旋律人声vocals+其他instrumentals_pth = %s
79 | sha256_uvr5_HP5_only_main_vocal_pth = %s
80 | sha256_uvr5_VR-DeEchoAggressive_pth = %s
81 | sha256_uvr5_VR-DeEchoDeReverb_pth = %s
82 | sha256_uvr5_VR-DeEchoNormal_pth = %s
83 | sha256_uvr5_vocals_onnx = %s
84 | `
85 |
--------------------------------------------------------------------------------
/tools/cmd/calc_rvc_model_similarity.py:
--------------------------------------------------------------------------------
1 | # This code references https://huggingface.co/JosephusCheung/ASimilarityCalculatior/blob/main/qwerty.py
2 | # Fill in the path of the model to be queried and the root directory of the reference models, and this script will return the similarity between the model to be queried and all reference models.
3 | import os
4 | import logging
5 |
6 | logger = logging.getLogger(__name__)
7 |
8 | import torch
9 | import torch.nn as nn
10 | import torch.nn.functional as F
11 |
12 |
13 | def cal_cross_attn(to_q, to_k, to_v, rand_input):
14 | hidden_dim, embed_dim = to_q.shape
15 | attn_to_q = nn.Linear(hidden_dim, embed_dim, bias=False)
16 | attn_to_k = nn.Linear(hidden_dim, embed_dim, bias=False)
17 | attn_to_v = nn.Linear(hidden_dim, embed_dim, bias=False)
18 | attn_to_q.load_state_dict({"weight": to_q})
19 | attn_to_k.load_state_dict({"weight": to_k})
20 | attn_to_v.load_state_dict({"weight": to_v})
21 |
22 | return torch.einsum(
23 | "ik, jk -> ik",
24 | F.softmax(
25 | torch.einsum("ij, kj -> ik", attn_to_q(rand_input), attn_to_k(rand_input)),
26 | dim=-1,
27 | ),
28 | attn_to_v(rand_input),
29 | )
30 |
31 |
32 | def model_hash(filename):
33 | try:
34 | with open(filename, "rb") as file:
35 | import hashlib
36 |
37 | m = hashlib.sha256()
38 |
39 | file.seek(0x100000)
40 | m.update(file.read(0x10000))
41 | return m.hexdigest()[0:8]
42 | except FileNotFoundError:
43 | return "NOFILE"
44 |
45 |
46 | def eval(model, n, input):
47 | qk = f"enc_p.encoder.attn_layers.{n}.conv_q.weight"
48 | uk = f"enc_p.encoder.attn_layers.{n}.conv_k.weight"
49 | vk = f"enc_p.encoder.attn_layers.{n}.conv_v.weight"
50 | atoq, atok, atov = model[qk][:, :, 0], model[uk][:, :, 0], model[vk][:, :, 0]
51 |
52 | attn = cal_cross_attn(atoq, atok, atov, input)
53 | return attn
54 |
55 |
56 | def main(path, root):
57 | torch.manual_seed(114514)
58 | model_a = torch.load(path, map_location="cpu")["weight"]
59 |
60 | logger.info("Query:\t\t%s\t%s" % (path, model_hash(path)))
61 |
62 | map_attn_a = {}
63 | map_rand_input = {}
64 | for n in range(6):
65 | hidden_dim, embed_dim, _ = model_a[
66 | f"enc_p.encoder.attn_layers.{n}.conv_v.weight"
67 | ].shape
68 | rand_input = torch.randn([embed_dim, hidden_dim])
69 |
70 | map_attn_a[n] = eval(model_a, n, rand_input)
71 | map_rand_input[n] = rand_input
72 |
73 | del model_a
74 |
75 | for name in sorted(list(os.listdir(root))):
76 | path = "%s/%s" % (root, name)
77 | model_b = torch.load(path, map_location="cpu")["weight"]
78 |
79 | sims = []
80 | for n in range(6):
81 | attn_a = map_attn_a[n]
82 | attn_b = eval(model_b, n, map_rand_input[n])
83 |
84 | sim = torch.mean(torch.cosine_similarity(attn_a, attn_b))
85 | sims.append(sim)
86 |
87 | logger.info(
88 | "Reference:\t%s\t%s\t%s"
89 | % (path, model_hash(path), f"{torch.mean(torch.stack(sims)) * 1e2:.2f}%")
90 | )
91 |
92 |
93 | if __name__ == "__main__":
94 | query_path = r"assets\weights\mi v3.pth"
95 | reference_root = r"assets\weights"
96 | main(query_path, reference_root)
97 |
--------------------------------------------------------------------------------
/tools/cmd/infer_batch_rvc.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import os
3 | import sys
4 |
5 | print("Command-line arguments:", sys.argv)
6 |
7 | now_dir = os.getcwd()
8 | sys.path.append(now_dir)
9 | import sys
10 |
11 | import tqdm as tq
12 | from dotenv import load_dotenv
13 | from scipy.io import wavfile
14 |
15 | from configs import Config
16 | from infer.modules.vc import VC
17 |
18 |
19 | def arg_parse() -> tuple:
20 | parser = argparse.ArgumentParser()
21 | parser.add_argument("--f0up_key", type=int, default=0)
22 | parser.add_argument("--input_path", type=str, help="input path")
23 | parser.add_argument("--index_path", type=str, help="index path")
24 | parser.add_argument("--f0method", type=str, default="harvest", help="harvest or pm")
25 | parser.add_argument("--opt_path", type=str, help="opt path")
26 | parser.add_argument("--model_name", type=str, help="store in assets/weight_root")
27 | parser.add_argument("--index_rate", type=float, default=0.66, help="index rate")
28 | parser.add_argument("--device", type=str, help="device")
29 | parser.add_argument("--is_half", type=bool, help="use half -> True")
30 | parser.add_argument("--filter_radius", type=int, default=3, help="filter radius")
31 | parser.add_argument("--resample_sr", type=int, default=0, help="resample sr")
32 | parser.add_argument("--rms_mix_rate", type=float, default=1, help="rms mix rate")
33 | parser.add_argument("--protect", type=float, default=0.33, help="protect")
34 |
35 | args = parser.parse_args()
36 | sys.argv = sys.argv[:1]
37 |
38 | return args
39 |
40 |
41 | def main():
42 | load_dotenv()
43 | args = arg_parse()
44 | config = Config()
45 | config.device = args.device if args.device else config.device
46 | config.is_half = args.is_half if args.is_half else config.is_half
47 | vc = VC(config)
48 | vc.get_vc(args.model_name)
49 | audios = os.listdir(args.input_path)
50 | for file in tq.tqdm(audios):
51 | if file.endswith(".wav"):
52 | file_path = os.path.join(args.input_path, file)
53 | _, wav_opt = vc.vc_single(
54 | 0,
55 | file_path,
56 | args.f0up_key,
57 | None,
58 | args.f0method,
59 | args.index_path,
60 | None,
61 | args.index_rate,
62 | args.filter_radius,
63 | args.resample_sr,
64 | args.rms_mix_rate,
65 | args.protect,
66 | )
67 | out_path = os.path.join(args.opt_path, file)
68 | wavfile.write(out_path, wav_opt[0], wav_opt[1])
69 |
70 |
71 | if __name__ == "__main__":
72 | main()
73 |
--------------------------------------------------------------------------------
/tools/cmd/infer_cli.py:
--------------------------------------------------------------------------------
1 | import argparse
2 | import os
3 | import sys
4 |
5 | now_dir = os.getcwd()
6 | sys.path.append(now_dir)
7 | from dotenv import load_dotenv
8 | from scipy.io import wavfile
9 |
10 | from configs import Config
11 | from infer.modules.vc import VC
12 |
13 | ####
14 | # USAGE
15 | #
16 | # In your Terminal or CMD or whatever
17 |
18 |
19 | def arg_parse() -> tuple:
20 | parser = argparse.ArgumentParser()
21 | parser.add_argument("--f0up_key", type=int, default=0)
22 | parser.add_argument("--input_path", type=str, help="input path")
23 | parser.add_argument("--index_path", type=str, help="index path")
24 | parser.add_argument("--f0method", type=str, default="harvest", help="harvest or pm")
25 | parser.add_argument("--opt_path", type=str, help="opt path")
26 | parser.add_argument("--model_name", type=str, help="store in assets/weight_root")
27 | parser.add_argument("--index_rate", type=float, default=0.66, help="index rate")
28 | parser.add_argument("--device", type=str, help="device")
29 | parser.add_argument("--is_half", type=bool, help="use half -> True")
30 | parser.add_argument("--filter_radius", type=int, default=3, help="filter radius")
31 | parser.add_argument("--resample_sr", type=int, default=0, help="resample sr")
32 | parser.add_argument("--rms_mix_rate", type=float, default=1, help="rms mix rate")
33 | parser.add_argument("--protect", type=float, default=0.33, help="protect")
34 |
35 | args = parser.parse_args()
36 | sys.argv = sys.argv[:1]
37 |
38 | return args
39 |
40 |
41 | def main():
42 | load_dotenv()
43 | args = arg_parse()
44 | config = Config()
45 | config.device = args.device if args.device else config.device
46 | config.is_half = args.is_half if args.is_half else config.is_half
47 | vc = VC(config)
48 | vc.get_vc(args.model_name)
49 | _, wav_opt = vc.vc_single(
50 | 0,
51 | args.input_path,
52 | args.f0up_key,
53 | None,
54 | args.f0method,
55 | args.index_path,
56 | None,
57 | args.index_rate,
58 | args.filter_radius,
59 | args.resample_sr,
60 | args.rms_mix_rate,
61 | args.protect,
62 | )
63 | wavfile.write(args.opt_path, wav_opt[0], wav_opt[1])
64 |
65 |
66 | if __name__ == "__main__":
67 | main()
68 |
--------------------------------------------------------------------------------
/tools/cmd/onnx/export.py:
--------------------------------------------------------------------------------
1 | from rvc.onnx import export_onnx
2 |
3 | export_onnx("pt/Justin Bieber.pth", "pt/TestRvc_Rvc.onnx")
4 |
--------------------------------------------------------------------------------
/tools/cmd/onnx/infer.py:
--------------------------------------------------------------------------------
1 | import librosa
2 |
3 | from rvc.onnx import RVC
4 |
5 | from infer.lib.audio import save_audio
6 |
7 | hop_size = 512
8 | sampling_rate = 40000 # 采样率
9 | f0_up_key = 0 # 升降调
10 | sid = 0 # 角色ID
11 | f0_method = "dio" # F0提取算法
12 | model_path = "exported_model.onnx" # 模型的完整路径
13 | vec_path = "vec-256-layer-9.onnx" # 需要onnx的vec模型
14 | wav_path = "123.wav" # 输入路径或ByteIO实例
15 | out_path = "out.wav" # 输出路径或ByteIO实例
16 |
17 | model = RVC(model_path, vec_path=vec_path, hop_len=hop_size, device="cuda")
18 |
19 | wav, sr = librosa.load(wav_path, sr=sampling_rate)
20 |
21 | audio = model.infer(wav, sr, sampling_rate, sid, f0_method, f0_up_key)
22 |
23 | save_audio(out_path, audio, sampling_rate)
24 |
--------------------------------------------------------------------------------
/tools/cmd/train-index-v2.py:
--------------------------------------------------------------------------------
1 | """
2 | 格式:直接cid为自带的index位;aid放不下了,通过字典来查,反正就5w个
3 | """
4 |
5 | import os
6 | import traceback
7 | import logging
8 |
9 | logger = logging.getLogger(__name__)
10 |
11 | from multiprocessing import cpu_count
12 |
13 | import faiss
14 | import numpy as np
15 | from sklearn.cluster import MiniBatchKMeans
16 |
17 | # ###########如果是原始特征要先写save
18 | n_cpu = 0
19 | if n_cpu == 0:
20 | n_cpu = cpu_count()
21 | inp_root = r"./logs/anz/3_feature768"
22 | npys = []
23 | listdir_res = list(os.listdir(inp_root))
24 | for name in sorted(listdir_res):
25 | phone = np.load("%s/%s" % (inp_root, name))
26 | npys.append(phone)
27 | big_npy = np.concatenate(npys, 0)
28 | big_npy_idx = np.arange(big_npy.shape[0])
29 | np.random.shuffle(big_npy_idx)
30 | big_npy = big_npy[big_npy_idx]
31 | logger.debug(big_npy.shape) # (6196072, 192)#fp32#4.43G
32 | if big_npy.shape[0] > 2e5:
33 | # if(1):
34 | info = "Trying doing kmeans %s shape to 10k centers." % big_npy.shape[0]
35 | logger.info(info)
36 | try:
37 | big_npy = (
38 | MiniBatchKMeans(
39 | n_clusters=10000,
40 | verbose=True,
41 | batch_size=256 * n_cpu,
42 | compute_labels=False,
43 | init="random",
44 | )
45 | .fit(big_npy)
46 | .cluster_centers_
47 | )
48 | except:
49 | info = traceback.format_exc()
50 | logger.warning(info)
51 |
52 | np.save("tools/infer/big_src_feature_mi.npy", big_npy)
53 |
54 | ##################train+add
55 | # big_npy=np.load("/bili-coeus/jupyter/jupyterhub-liujing04/vits_ch/inference_f0/big_src_feature_mi.npy")
56 | n_ivf = min(int(16 * np.sqrt(big_npy.shape[0])), big_npy.shape[0] // 39)
57 | index = faiss.index_factory(768, "IVF%s,Flat" % n_ivf) # mi
58 | logger.info("Training...")
59 | index_ivf = faiss.extract_index_ivf(index) #
60 | index_ivf.nprobe = 1
61 | index.train(big_npy)
62 | faiss.write_index(
63 | index, "tools/infer/trained_IVF%s_Flat_baseline_src_feat_v2.index" % (n_ivf)
64 | )
65 | logger.info("Adding...")
66 | batch_size_add = 8192
67 | for i in range(0, big_npy.shape[0], batch_size_add):
68 | index.add(big_npy[i : i + batch_size_add])
69 | faiss.write_index(
70 | index, "tools/infer/added_IVF%s_Flat_mi_baseline_src_feat.index" % (n_ivf)
71 | )
72 | """
73 | 大小(都是FP32)
74 | big_src_feature 2.95G
75 | (3098036, 256)
76 | big_emb 4.43G
77 | (6196072, 192)
78 | big_emb双倍是因为求特征要repeat后再加pitch
79 |
80 | """
81 |
--------------------------------------------------------------------------------
/tools/cmd/train-index.py:
--------------------------------------------------------------------------------
1 | """
2 | 格式:直接cid为自带的index位;aid放不下了,通过字典来查,反正就5w个
3 | """
4 |
5 | import os
6 | import logging
7 |
8 | logger = logging.getLogger(__name__)
9 |
10 | import faiss
11 | import numpy as np
12 |
13 | # ###########如果是原始特征要先写save
14 | inp_root = r"E:\codes\py39\dataset\mi\2-co256"
15 | npys = []
16 | for name in sorted(list(os.listdir(inp_root))):
17 | phone = np.load("%s/%s" % (inp_root, name))
18 | npys.append(phone)
19 | big_npy = np.concatenate(npys, 0)
20 | logger.debug(big_npy.shape) # (6196072, 192)#fp32#4.43G
21 | np.save("infer/big_src_feature_mi.npy", big_npy)
22 |
23 | ##################train+add
24 | # big_npy=np.load("/bili-coeus/jupyter/jupyterhub-liujing04/vits_ch/inference_f0/big_src_feature_mi.npy")
25 | logger.debug(big_npy.shape)
26 | index = faiss.index_factory(256, "IVF512,Flat") # mi
27 | logger.info("Training...")
28 | index_ivf = faiss.extract_index_ivf(index) #
29 | index_ivf.nprobe = 9
30 | index.train(big_npy)
31 | faiss.write_index(index, "infer/trained_IVF512_Flat_mi_baseline_src_feat.index")
32 | logger.info("Adding...")
33 | index.add(big_npy)
34 | faiss.write_index(index, "infer/added_IVF512_Flat_mi_baseline_src_feat.index")
35 | """
36 | 大小(都是FP32)
37 | big_src_feature 2.95G
38 | (3098036, 256)
39 | big_emb 4.43G
40 | (6196072, 192)
41 | big_emb双倍是因为求特征要repeat后再加pitch
42 |
43 | """
44 |
--------------------------------------------------------------------------------
/tools/cmd/trans_weights.py:
--------------------------------------------------------------------------------
1 | import pdb
2 |
3 | import torch
4 |
5 | # a=torch.load(r"E:\codes\py39\vits_vc_gpu_train\logs\ft-mi-suc\G_1000.pth")["model"]#sim_nsf#
6 | # a=torch.load(r"E:\codes\py39\vits_vc_gpu_train\logs\ft-mi-freeze-vocoder-flow-enc_q\G_1000.pth")["model"]#sim_nsf#
7 | # a=torch.load(r"E:\codes\py39\vits_vc_gpu_train\logs\ft-mi-freeze-vocoder\G_1000.pth")["model"]#sim_nsf#
8 | # a=torch.load(r"E:\codes\py39\vits_vc_gpu_train\logs\ft-mi-test\G_1000.pth")["model"]#sim_nsf#
9 | a = torch.load(
10 | r"E:\codes\py39\vits_vc_gpu_train\logs\ft-mi-no_opt-no_dropout\G_1000.pth"
11 | )[
12 | "model"
13 | ] # sim_nsf#
14 | for key in a.keys():
15 | a[key] = a[key].half()
16 | # torch.save(a,"ft-mi-freeze-vocoder_true_1k.pt")#
17 | # torch.save(a,"ft-mi-sim1k.pt")#
18 | torch.save(a, "ft-mi-no_opt-no_dropout.pt") #
19 |
--------------------------------------------------------------------------------