diff --git a/README.md b/README.md index 2a09d77..5a8b3fb 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,544 @@ -# Fase 2: dataset per classificatore italiano +# EPUB Corrector RKNN -Genera coppie bilanciate `[frase A, frase B]`, dove la label indica se B è la versione corretta. +Correttore e revisore di EPUB italiani per Orange Pi 5 Plus / RK3588. -```bash -python make_training_pairs.py ~/epub-corrector/input/a.epub --pairs 20000 --output pairs.jsonl -python check_dataset.py pairs.jsonl -python split_dataset.py pairs.jsonl --outdir data +La pipeline combina: + +- LanguageTool locale per generare i candidati; +- Hunspell italiano per il controllo lessicale; +- modello BERT in formato RKNN FP16 sulla NPU RK3588; +- memoria incrementale di approvazioni, rifiuti e parole da preservare; +- interfaccia Web per revisione, riscrittura e creazione di una copia EPUB corretta. + +## Requisiti verificati + +- Orange Pi 5 Plus o altro dispositivo RK3588 / RKNPU v2 +- Linux aarch64 +- Python 3.11 +- RKNNLite 2.3.2 +- RKNN Runtime 2.3.2 +- driver NPU 0.9.8 +- Docker per LanguageTool +- Git LFS per scaricare il modello RKNN + +## Installazione in una nuova directory + +L'esempio installa il progetto in: + +```text +/home/nvme/epub-corrector-new ``` -Nota: usare un solo libro rischia overfitting stilistico. Questa è una prova di fattibilità; per il modello finale servono più fonti italiane pulite e un test manuale separato. +### 1. Installa i pacchetti di sistema + +```bash +sudo apt update +sudo apt install -y \ + git \ + git-lfs \ + python3-venv \ + hunspell \ + hunspell-it \ + unzip + +git lfs install +``` + +### 2. Clona il repository + +```bash +cd /home/nvme + +git clone \ + 'https://forgit.patachina.it/Fabio/epub_corrector.git' \ + epub-corrector-new + +cd /home/nvme/epub-corrector-new + +git lfs pull +git lfs checkout +``` + +Per l'autenticazione HTTPS usare: + +```text +Username: Fabio +Password: Personal Access Token di Forgit +``` + +### 3. Verifica il modello RKNN + +Il modello deve misurare circa 214 MB, non pochi byte. + +```bash +ls -lh \ + rknn/bert-pair-v2-eager-fp16.rknn + +sha256sum -c \ + rknn/bert-pair-v2-eager-fp16.sha256 +``` + +Risultato richiesto: + +```text +rknn/bert-pair-v2-eager-fp16.rknn: OK +``` + +Se il modello non è stato scaricato: + +```bash +git lfs pull +git lfs checkout +``` + +### 4. Crea l'ambiente Python + +```bash +cd /home/nvme/epub-corrector-new + +python3 -m venv .venv-rknn +source .venv-rknn/bin/activate + +python -m pip install --upgrade \ + pip \ + setuptools \ + wheel + +python -m pip install \ + -r requirements-rknn.txt +``` + +### 5. Installa RKNNLite 2.3.2 + +RKNNLite può richiedere la wheel ufficiale Rockchip compatibile con: + +```text +Python 3.11 +Linux aarch64 +RK3588 +``` + +Verifica prima se è già disponibile: + +```bash +python - <<'PY' +from rknnlite.api import RKNNLite +print("RKNNLite disponibile") +PY +``` + +Se non è disponibile, trova la wheel usata nella vecchia installazione: + +```bash +find \ + /home/nvme \ + /home/orangepi \ + -type f \ + -iname '*rknn*lite*.whl' \ + 2>/dev/null +``` + +Installala indicando il percorso reale: + +```bash +python -m pip install \ + /percorso/rknn_toolkit_lite2-2.3.2-*.whl +``` + +Verifica nuovamente l'importazione. + +### 6. Crea le directory locali + +Queste directory non vengono memorizzate nel repository perché possono contenere EPUB o testo protetto da copyright. + +```bash +mkdir -p \ + output \ + reports \ + runs/ui \ + review_memory +``` + +Inizializza la memoria automatica: + +```bash +printf '%s\n' \ + '{' \ + ' "approved": [],' \ + ' "sentence_rewrites": [],' \ + ' "preserved": [],' \ + ' "rejected": []' \ + '}' \ + > review_memory/auto_memory.json +``` + +Per importare la memoria da una precedente installazione: + +```bash +cp \ + /vecchia/installazione/review_memory/auto_memory.json \ + review_memory/auto_memory.json +``` + +La memoria precedente è facoltativa e può contenere decisioni specifiche di altri libri. + +### 7. Aggiorna i percorsi della nuova installazione + +Cerca eventuali percorsi assoluti rimasti dalla vecchia directory: + +```bash +grep -RIn \ + '/home/nvme/epub-gec-experiment' \ + --include='*.py' \ + --include='*.service' \ + --include='*.sh' \ + --include='*.json' \ + . +``` + +Sostituiscili con il nuovo percorso: + +```bash +grep -Rl \ + '/home/nvme/epub-gec-experiment' \ + --include='*.py' \ + --include='*.service' \ + --include='*.sh' \ + --include='*.json' \ + . | \ +xargs -r sed -i \ + 's|/home/nvme/epub-gec-experiment|/home/nvme/epub-corrector-new|g' +``` + +Verifica: + +```bash +grep -RIn \ + '/home/nvme/epub-gec-experiment' \ + --include='*.py' \ + --include='*.service' \ + --include='*.sh' \ + --include='*.json' \ + . || echo "Nessun vecchio percorso rimasto" +``` + +### 8. Verifica il percorso del tokenizer + +Il tokenizer incluso nel repository si trova in: + +```text +assets/tokenizer/tokenizer.json +``` + +Cerca eventuali riferimenti al vecchio percorso: + +```bash +grep -RIn \ + 'onnx/bert-pair-v2/tokenizer' \ + --include='*.py' \ + . +``` + +Se necessario, sostituiscili: + +```bash +grep -Rl \ + 'onnx/bert-pair-v2/tokenizer/tokenizer.json' \ + --include='*.py' \ + . | \ +xargs -r sed -i \ + 's|onnx/bert-pair-v2/tokenizer/tokenizer.json|assets/tokenizer/tokenizer.json|g' +``` + +### 9. Prepara la cartella degli EPUB + +Puoi riutilizzare la cartella esistente: + +```text +/home/orangepi/epub-corrector/input +``` + +Oppure crearne una nuova: + +```bash +mkdir -p \ + /home/orangepi/epub-corrector-new/input +``` + +Se usi una nuova cartella, aggiorna `INPUT` in `epub-corrector-ui-app/app.py`: + +```bash +sed -i \ + "s|INPUT=Path('/home/orangepi/epub-corrector/input')|INPUT=Path('/home/orangepi/epub-corrector-new/input')|" \ + epub-corrector-ui-app/app.py +``` + +### 10. Avvia LanguageTool + +Se il container esiste già: + +```bash +sudo docker start languagetool-epub +``` + +Controlla: + +```bash +sudo docker ps \ + --filter name=languagetool-epub \ + --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}' +``` + +Testa l'endpoint locale: + +```bash +LT_URL="$( + printf 'http:%s127.0.0.1:8010/v2/check' '//' +)" + +curl -sS \ + -X POST \ + -d 'language=it-IT' \ + --data-urlencode 'text=Questa frase contiene un erore.' \ + "$LT_URL" \ + -o /tmp/languagetool-test.json + +python -m json.tool \ + /tmp/languagetool-test.json | \ +head -n 30 +``` + +La risposta deve contenere `matches`. + +Se il container non esiste, crealo: + +```bash +sudo docker run -d \ + --name languagetool-epub \ + --restart unless-stopped \ + -p 127.0.0.1:8010:8010 \ + --memory=1200m \ + -e Java_Xms=128m \ + -e Java_Xmx=768m \ + silviof/docker-languagetool +``` + +### 11. Verifica la NPU + +```bash +source /home/nvme/epub-corrector-new/.venv-rknn/bin/activate + +python - <<'PY' +from pathlib import Path +from rknnlite.api import RKNNLite + +model = Path( + "rknn/bert-pair-v2-eager-fp16.rknn" +) + +if not model.exists(): + raise SystemExit(f"Modello assente: {model}") + +rknn = RKNNLite(verbose=False) + +try: + result = rknn.load_rknn(str(model)) + print("load_rknn:", result) + + if result != 0: + raise SystemExit(result) + + result = rknn.init_runtime( + core_mask=RKNNLite.NPU_CORE_AUTO + ) + + print("init_runtime:", result) + + if result != 0: + raise SystemExit(result) + + print("MODELLO NPU PRONTO") +finally: + rknn.release() +PY +``` + +Il warning relativo a `RKNN_QUERY_INPUT_DYNAMIC_RANGE` può essere ignorato: il modello usa forma statica a 128 token. + +## Installazione della Web UI + +### 12. Crea il servizio systemd + +Se la precedente installazione usa ancora la porta 8090, fermala o scegli la porta 8091 per la nuova. + +Per disabilitare il vecchio servizio: + +```bash +sudo systemctl disable --now \ + epub-corrector-ui +``` + +Crea un servizio per la nuova directory: + +```bash +SERVICE_FILE="/etc/systemd/system/epub-corrector-new.service" + +sudo sh -c "printf '%s\n' \ +'[Unit]' \ +'Description=EPUB Corrector New Web UI' \ +'After=network.target docker.service' \ +'Wants=docker.service' \ +'' \ +'[Service]' \ +'Type=simple' \ +'User=orangepi' \ +'WorkingDirectory=/home/nvme/epub-corrector-new' \ +'ExecStart=/home/nvme/epub-corrector-new/.venv-rknn/bin/python /home/nvme/epub-corrector-new/epub-corrector-ui-app/app.py' \ +'Restart=on-failure' \ +'RestartSec=5' \ +'Environment=PYTHONUNBUFFERED=1' \ +'' \ +'[Install]' \ +'WantedBy=multi-user.target' \ +> '$SERVICE_FILE'" +``` + +Se vuoi mantenere due installazioni attive, modifica la porta della nuova UI: + +```bash +sed -i \ + 's/port=8090/port=8091/' \ + epub-corrector-ui-app/app.py +``` + +Avvia il servizio: + +```bash +sudo systemctl daemon-reload +sudo systemctl enable --now \ + epub-corrector-new + +sudo systemctl status \ + epub-corrector-new \ + --no-pager -l +``` + +Controlla la porta: + +```bash +sudo ss -ltnp | \ +grep -E ':8090|:8091' +``` + +### 13. Apri l'interfaccia + +Trova l'indirizzo dell'Orange Pi: + +```bash +hostname -I +``` + +Apri dal browser: + +```text +http://IP_ORANGE_PI:8090 +``` + +oppure, se hai scelto la porta alternativa: + +```text +http://IP_ORANGE_PI:8091 +``` + +## Uso + +1. Copia gli EPUB italiani senza DRM nella cartella `input`. +2. Apri la Web UI. +3. Avvia LanguageTool, se non è già attivo. +4. Seleziona il libro. +5. Premi **Analizza**. +6. Revisiona i candidati: + - **Approva proposta**; + - **Salva riscrittura**; + - **Mantieni e ricorda**; + - **Rifiuta**. +7. Premi **Crea EPUB corretto**. +8. Verifica il file prodotto nella cartella `output`. + +La memoria viene salvata in: + +```text +review_memory/auto_memory.json +``` + +La scansione successiva la carica automaticamente. + +## Validazione dell'EPUB prodotto + +```bash +unzip -t \ + output/NOME_LIBRO_ui_reviewed.epub +``` + +Controlla che `mimetype` sia il primo file e non sia compresso: + +```bash +unzip -lv \ + output/NOME_LIBRO_ui_reviewed.epub | \ +head -n 10 +``` + +Apri infine il file con Calibre, Thorium Reader o KOReader e controlla: + +- indice e capitoli; +- corsivi, link e note; +- dialoghi; +- riscritture complete; +- campioni delle sostituzioni applicate. + +## Backup della memoria + +```bash +cp -p \ + review_memory/auto_memory.json \ + "review_memory/auto_memory_$(date +%Y%m%d_%H%M%S).json" +``` + +## Aggiornamento da Git + +```bash +cd /home/nvme/epub-corrector-new + +git pull +git lfs pull + +sha256sum -c \ + rknn/bert-pair-v2-eager-fp16.sha256 + +sudo systemctl restart \ + epub-corrector-new +``` + +## Comandi del servizio + +```bash +sudo systemctl start epub-corrector-new +sudo systemctl stop epub-corrector-new +sudo systemctl restart epub-corrector-new +sudo systemctl status epub-corrector-new --no-pager -l +sudo journalctl -u epub-corrector-new -f +``` + +## File non inclusi nel repository + +Per ragioni di privacy, copyright e dimensione, il repository non contiene: + +- EPUB originali o corretti; +- report con testo dei libri; +- memoria personale; +- dataset di addestramento; +- ambienti virtuali; +- ONNX intermedi; +- log. + +Il modello RKNN pronto è invece incluso tramite Git LFS, insieme al tokenizer necessario.