How to install custom Piper voice model on HAOS installation?

Piper documentation tab says:
“Add custom voice files to the /share/piper directory. Each custom voice must include a model file (<voice>.onnx) and config file (<voice>.onnx.json)”

I’ve made a custom voice and tried adding the result files in /share/piper and restarting everything (even the whole OS), but so far I haven’t been able to get the custom model in use. There are no mentions of the model in Piper logs either. Should it appear in the list of usable voices?
Is the documentation up-to-date and is the mentioned /share directory the one that that’s exported as SMB share? (as it could also mean the container’s internal share directory, which may not have linkage with the mentioned /share dir)
I’m using HA 2023.9.2 on HAOS 10.5 on KVM virtualization platform.

I respond to myself, maybe it helps someone else:
I succeeded to get my own model files in use by manually copying them (both .onnx and .onnx.json) into the data directory /mnt/data/supervisor/addons/data/core_piper using the existing model’s name.

Also had to change the MD5 hashes and file sizes accordingly in voices.json, and to disable model downloading from config dialog so that voices.json wouldn’t get overwritten. That had to be done in root-shell (ssh to port 22222), so it’s not the intended way to do it, but a workaround…

I.e. by doing this in shell:
cp /mnt/data/supervisor/share/piper/fi_FI-harri-medium.* /mnt/data/supervisor/addons/data/core_piper/
and then:
md5sum fi_FI-harri-medium.*
ls -la fi_FI-harri-medium.*
and manually updating those values into voices.json

2 Likes

Wondering if anyone else got this working?
I’m running
Home Assistant 2023.10.1
OS 10.5
But it seems that I do not have the dirs that @jroine mentioned.

Running into the same issue as well… uploaded to /share/piper but its not finding the voices.

I have working config in this.
HAOS 2023.11.1, OS 2023.11.0

/share/piper/ko_KR-000-low.onnx
/share/piper/ko_KR-000-low.onnx.json

I’m having the same problem. Any help would be appreciated. I’m running everything on docker containers in case it helps.

That find and replace files in debug-shell is just a quick hack.
You should run your own instance of piper like this:

  1. Create a docker-compose.yml file:
services:
  piper:
    container_name: piper
    image: rhasspy/wyoming-piper:latest
    command: --voice fi_FI-myvoice-medium
    volumes:
      - ./piper:/data
      - ./voices.json:/usr/local/lib/python3.9/dist-packages/wyoming_piper/voices.json:ro
    restart: always
    ports:
      - 10200:10200

If due to version change the voices.json location changes, you need to find the file in the container and use that path instead. It can be done like this (when container is set up):

docker exec -it piper find / -name voices.json

  1. File voices.json must have an entry of your custom voice model (naturally you need to use your files md5 sums and sizes in size_bytes and md5_digest):
{
    "fi_FI-myvoice-medium": {
        "key": "fi_FI-myvoice-medium",
        "name": "myvoice",
        "language": {
            "code": "fi_FI",
            "family": "fi",
            "region": "FI",
            "name_native": "Suomi",
            "name_english": "Finnish",
            "country_english": "Finland"
        },
        "quality": "medium",
        "num_speakers": 1,
        "speaker_id_map": {},
        "files": {
            "fi_FI-myvoice-medium.onnx": {
                "size_bytes": 12345678,
                "md5_digest": "ffffffffffffffffffffffffffffffff"
            },
            "fi_FI-myvoice-medium.onnx.json": {
                "size_bytes": 1234,
                "md5_digest": "ffffffffffffffffffffffffffffffff"
            },
            "MODEL_CARD": {
                "size_bytes": 304,
                "md5_digest": "95d5aff86d27b69c8ee7deed6c056aff"
            }
        },
        "aliases": []
    }
}

I’m not sure is the MODEL_CARD entry needed, but I just copied it from existing. It doesn’t seem to affect on the result.

  1. Add your model files (onnx and onnx.json files) to piper dir.
    The directory should now look like:
docker-compose.yml
voices.json
piper/fi_FI-myvoice-medium.onnx
piper/fi_FI-myvoice-medium.onnx.json
piper/MODEL_CARD

Then run command

docker-compose up

Finally, add new wyoming-protocol entry with the ip and port of this container.

I don’t understand why changing voices.json isn’t made any easier (or maybe it is, but poorly documented?) IMHO it should first check if /data/voices.json exists and use that instead. Or merge that with original voices.json.

1 Like

Hmm… actually it seems that voices.json override is not needed (anymore?)

I’m trying to add a voice but I do not have the folder /mnt/data/supervisor/addons/data/core_piper so I am not sure where the files should be located. I have piper installed and it’s working fine I just can’t find any onnx files. I’ve tried through file browser in HA, SSH, and through windows file explore. Any ideas?

Would you mind posting the start of your json? I think there is something in my json that is preventing my onnx from working.

I can’t seem to find anything in my share folder? Should there be a piper folder there? Or do I need to create it?

You have to create the piper folder first (be careful with access permissions).

I managed to make it work by changing the file name so that it matches the dataset name in the json file, e.g. this is my (Italian) giulia.onnx.json:

{
    "dataset": "giulia",
    "audio": {
        "sample_rate": 22050,
        "quality": "medium"
    },
    "espeak": {
        "voice": "it"
    },
    "inference": {
        "noise_scale": 0.667,
        "length_scale": 1,
        "noise_w": 0.8
    },
    "phoneme_type": "espeak",
    "phoneme_map": {},
    "phoneme_id_map": { 
       <YOUR MAP HERE>
    },
    "num_symbols": 256,
    "num_speakers": 1,
    "speaker_id_map": {},
    "language": {
      "code": "it_IT",
      "family": "it",
      "region": "IT",
      "name_native": "Italiano",
      "name_english": "Italian",
      "country_english": "Italy"
    },
    "piper_version": "1.0.0"
}

I still have to specify the voice in every tts piper call, because for some reason it doesn’t appear in the piper addon dropdown menu (only in the Voice Assistant menu), but it works:

service: tts.speak
data:
  cache: true
  message: MESSAGE
  media_player_entity_id: media_player.YOUR-MEDIA-PLAYER
  options:
    voice: giulia
target:
  entity_id: tts.piper

Any idea how I can convert a voice made in Applio to piper?