Certo. Ti preparo una guida riutilizzabile per generare più modelli RKNN di CosyVoice3 Flow Estimator, uno per ogni sequenza (per esempio 200, 256, 500 e, se sostenibile, altre). L'idea è mantenere un modello separato per ogni lunghezza, senza modificare quelli già funzionanti. Alla fine avremo una procedura per convertire, verificare e trasferire i file `.rknn` sull'Orange Pi, oltre a una tabella per scegliere quale sequenza usare durante l'inferenza. La conversione va fatta sulla VM Debian 12 x86_64, non sull'Orange Pi: la VM usa Python 3.11 e RKNN-Toolkit2; l'Orange Pi serve per caricare e provare i `.rknn` con `librknnrt`. È anche il flusso previsto da Rockchip: conversione sul computer host e inferenza sul dispositivo. [image](https://www.google.com/s2/favicons?domain=https://github.com\&sz=32) GitHub+1 Nel nostro caso useremo sempre la stessa base: - ONNX FP32: `/mnt/rknn-work/cosyvoice3-official/flow.decoder.estimator.fp32.onnx` - Script: `tools/rknn/prepare_cosyvoice3_rknn_flow.py` - Target: `rk3588` - Precisione: FP16, senza quantizzazione INT8 - Ottimizzazione: livello `3` # Guida: conversione di CosyVoice3 Flow Estimator in RKNN per sequenze diverse ## 1. Ambiente di conversione La conversione si esegue sulla VM Debian 12 x86_64, non sull'Orange Pi. | Elemento | Percorso / versione | | ------------------- | --------------------------------------------------------------------- | | Repository | `/home/fabio/audio-cpp-rknn-upstream` | | Ambiente Python | `rknn-env` | | Python | 3.11 | | Script | `tools/rknn/prepare_cosyvoice3_rknn_flow.py` | | Modello ONNX FP32 | `/mnt/rknn-work/cosyvoice3-official/flow.decoder.estimator.fp32.onnx` | | SoC di destinazione | `rk3588` | | Precisione | FP16 | | Quantizzazione INT8 | Disattivata | | Optimization level | `3` | Non occorre reinstallare RKNN-Toolkit2 se l'ambiente virtuale esistente funziona. ## 2. Preparare il terminale Sulla VM: ``` cd /home/fabio/audio-cpp-rknn-upstream source rknn-env/bin/activate ``` Controllare che Python e il Toolkit siano quelli dell'ambiente: ``` python3 -c "import sys; from rknn.api import RKNN; print(sys.version); print('RKNN Toolkit import OK')" ``` Verificare che il modello ONNX esista: ``` ls -lh /mnt/rknn-work/cosyvoice3-official/flow.decoder.estimator.fp32.onnx ``` ## 3. Generare più sequenze in una sola conversione Lo script accetta più parametri `--seq-len` nella stessa esecuzione. Esempio: generare le sequenze 200, 256 e 500 in una nuova directory, senza sovrascrivere i modelli già creati: ``` python3 tools/rknn/prepare_cosyvoice3_rknn_flow.py \ --estimator-onnx /mnt/rknn-work/cosyvoice3-official/flow.decoder.estimator.fp32.onnx \ --seq-len 200 \ --seq-len 256 \ --seq-len 500 \ --target rk3588 \ --opt-level 3 \ --output-dir /mnt/rknn-work/cosyvoice3-rknn-fp16-multi ``` Il risultato atteso è una serie di file: ``` /mnt/rknn-work/cosyvoice3-rknn-fp16-multi/ ├── flow_estimator_seq200.rknn ├── flow_estimator_seq256.rknn └── flow_estimator_seq500.rknn ``` Ogni file è una variante del medesimo modello ONNX, preparata per una lunghezza di sequenza fissa. ### Generare una sola sequenza Per creare soltanto la sequenza 500, il comando è: ``` python3 tools/rknn/prepare_cosyvoice3_rknn_flow.py \ --estimator-onnx /mnt/rknn-work/cosyvoice3-official/flow.decoder.estimator.fp32.onnx \ --seq-len 500 \ --target rk3588 \ --opt-level 3 \ --output-dir /mnt/rknn-work/cosyvoice3-rknn-fp16-500 ``` Per creare, ad esempio, una sequenza 400, basta cambiare `--seq-len 500` in `--seq-len 400` e scegliere una nuova directory di output. **Importante:** ogni lunghezza deve corrispondere a un modello distinto. Non si deve rinominare un modello seq500 facendolo passare per seq400. ## 4. Significato delle opzioni | Opzione | Funzione | | ------------------ | ----------------------------------------------------------------------------------------------- | | `--estimator-onnx` | Indica il modello ONNX sorgente | | `--seq-len` | Lunghezza della sequenza da convertire; può essere ripetuta | | `--target rk3588` | Genera un modello destinato all'RK3588 | | `--opt-level 3` | Usa il livello di ottimizzazione 3 | | `--output-dir` | Directory in cui salvare i risultati | | `--check-frames` | Controlla le lunghezze dei frame indicate | | `--skip-rknn` | Esegue i controlli senza generare il file RKNN | | `--verify-sim` | Esegue la verifica di simulazione prevista dallo script; verifica il primo `--seq-len` indicato | Per verificare ogni sequenza con `--verify-sim`, è preferibile eseguire una conversione per volta, indicando una sola lunghezza per comando. `--skip-rknn` è utile per controllare la preparazione senza ripetere una conversione completa. ## 5. Verificare i file generati Dopo la conversione: ``` ls -lh /mnt/rknn-work/cosyvoice3-rknn-fp16-multi/ ``` Calcolare gli hash: ``` sha256sum /mnt/rknn-work/cosyvoice3-rknn-fp16-multi/*.rknn ``` Conservare gli hash: permettono di verificare che il file trasferito sull'Orange Pi sia identico all'originale. ### Controllo già superato per seq500 Il modello già prodotto è: ``` /mnt/rknn-work/cosyvoice3-rknn-fp16-500/flow_estimator_seq500.rknn ``` Dimensione esatta: ``` 717288588 byte ``` SHA256: ``` 27ffb3e5408bc07993913297cf265bb1d36d9632123514c4c6057fdcbdd3d7ee ``` ## 6. Verificare il caricamento sull'Orange Pi Il caricamento va verificato con il runtime RKNN presente sulla scheda. Il programma di test già compilato è: ``` /tmp/rknn_load_test ``` Esempio: ``` /tmp/rknn_load_test /home/nvme/cosyvoice3-rknn-fp16-500/flow_estimator_seq500.rknn ``` Un caricamento valido deve restituire: ``` rknn_init() = 0 API: 2.3.2 Driver: 0.9.8 Input: 6 Output: 1 rknn_destroy() = 0 ``` Questo controllo conferma che il runtime riesce a caricare e rilasciare il modello. Non equivale ancora a una prova di inferenza. ## 7. Eseguire una prova reale con CosyVoice3 Per provare un modello specifico, si indica il suo percorso nell'`exec_plan`. Esempio con seq500: ``` /tmp/audio-cpp-completo/build-cosyvoice3-rknn/bin/audiocpp_cli \ --task clon \ --family cosyvoice3 \ --model /home/nvme/audio-cpp-models/CosyVoice3-GGUF/cosyvoice3-q8_0.gguf \ --backend cpu \ --threads 4 \ --log \ --metrics \ --session-option 'cosyvoice3.exec_plan={"flow":{"impl":"rknn","artifacts":{"main":"/home/nvme/cosyvoice3-rknn-fp16-500/flow_estimator_seq500.rknn"}}}' \ --text "Buongiorno a tutti. Oggi vorrei raccontarvi una storia interessante. È una giornata speciale, piena di novità e di occasioni per imparare qualcosa di nuovo. Spero che possiate trascorrere momenti sereni, con entusiasmo e tanta voglia di fare. Vi auguro una splendida giornata e vi ringrazio per avermi ascoltato." \ --voice-ref /home/nvme/CosyVoice/mia_voce_2_3_9s.wav \ --reference-text "zia Ermia detta" \ --out /home/nvme/audio-cpp-models/test-cosyvoice3-seq500.wav ``` Per provare seq256 o seq200, si cambia soltanto il percorso del file `.rknn` e il nome del WAV di uscita. `--backend cpu` riguarda il backend del modello GGUF: non disabilita automaticamente RKNN per il Flow Estimator. L'implementazione del Flow è selezionata separatamente dall'`exec_plan`. ## 8. Come scegliere le sequenze La lunghezza della sequenza deve essere sufficiente per i frame richiesti dall'inferenza. | Modello | Capacità nominale | Impiego | | ------- | ----------------- | ----------------- | | seq200 | 200 frame | Test brevi | | seq256 | 256 frame | Test brevi e medi | | seq500 | 500 frame | Test più lunghi | Il programma può scegliere il modello più piccolo che contiene il numero di frame richiesto, se gli vengono forniti più modelli compatibili. Se la sequenza supera la capacità massima disponibile, il codice attuale può ricorrere al percorso CPU. ### Attenzione alla memoria NPU Sul nostro Orange Pi la memoria riservata dal driver è limitata. Il modello seq500 ha dimensioni su disco di circa 684 MiB, ma la sua occupazione durante il caricamento NPU è molto maggiore. Nei test già eseguiti, seq500 ha richiesto circa 3,7 GiB di memoria DMA. Per questo motivo non bisogna presumere che seq200, seq256 e seq500 possano essere caricati contemporaneamente. Per i test iniziali, caricare **un solo modello per volta**. In particolare, per provare seq500 non aggiungere contemporaneamente i modelli seq200 e seq256. ## 9. Tabella dei risultati da compilare Dopo ogni inferenza, annotare i dati dei log: | Modello | Frame richiesti | Tempo Flow | Tempo totale | Durata audio | RTF | Memoria massima | Esito | | ------- | --------------- | ---------- | ------------ | ------------ | ---- | --------------- | ----- | | seq200 |
|
|
|
|
|
|
| | seq256 |
|
|
|
|
|
|
| | seq500 |
|
|
|
|
|
|
| Per confrontare correttamente i modelli, usare la stessa frase, la stessa voce di riferimento, lo stesso testo di riferimento e le stesse impostazioni. ## 10. Procedura consigliata per ogni nuova sequenza 1. Partire sempre dal medesimo ONNX FP32. 2. Scegliere una nuova lunghezza con `--seq-len`. 3. Usare `--target rk3588` e `--opt-level 3`. 4. Generare il modello FP16 senza quantizzazione INT8. 5. Salvare il risultato in una directory dedicata, senza sovrascrivere modelli già verificati. 6. Controllare dimensione e SHA256. 7. Trasferire il modello sull'Orange Pi. 8. Verificare `rknn_init()` con il loader C++. 9. Eseguire una generazione audio reale. 10. Annotare tempi, RTF, memoria e qualità audio. **Regola fondamentale:** un `.rknn` che si carica correttamente non è ancora necessariamente un modello valido per l'inferenza. La verifica definitiva è una generazione audio reale con il Flow Estimator che utilizza effettivamente quel modello. Nota: seq200, seq256 e seq500 sono già stati generati in precedenza; seq500 è anche stato caricato correttamente sull'Orange Pi con RKNN API 2.3.2 e driver 0.9.8. La guida usa una nuova cartella `fp16-multi` negli esempi per non sovrascrivere quei risultati. ## 11. Repository di riferimento - Progetto originale audio.cpp: https://github.com/0xShug0/audio.cpp