docs: spec, lexicon, roadmap
This commit is contained in:
parent
b287617930
commit
ad397ae1bd
21
README.md
21
README.md
|
|
@ -0,0 +1,21 @@
|
|||
# ipin-vr
|
||||
|
||||
Generator prostych, **gramatycznie poprawnych** polskich poleceń do terapii afazji
|
||||
(np. *„Połóż jabłko na stole"*) wraz z wypowiadaniem ich przez Piper TTS.
|
||||
|
||||
Docelowo narzędzie ma działać w trybie mieszanej rzeczywistości na Meta Quest 3
|
||||
(offline). **Etap 1** (ten kod) realizuje wyłącznie rdzeń: generowanie poleceń i ich
|
||||
wypowiadanie na PC. Bez rozpoznawania mowy (STT), bez VR.
|
||||
|
||||
## Dokumentacja
|
||||
- [`docs/SPEC.md`](docs/SPEC.md) — specyfikacja techniczna etapu 1 (cel buildu).
|
||||
- [`docs/LEXICON.md`](docs/LEXICON.md) — zweryfikowany leksykon (formy gramatyczne).
|
||||
- [`docs/ROADMAP.md`](docs/ROADMAP.md) — etapy i ograniczenia platformy docelowej.
|
||||
|
||||
## Zasada naczelna
|
||||
Poprawność fleksji jest nienegocjowalna. Wszystkie formy słów pochodzą wyłącznie
|
||||
z ręcznie zweryfikowanego leksykonu; model językowy (gdy włączony) wybiera tylko
|
||||
identyfikatory elementów, a nie generuje polskiego tekstu.
|
||||
|
||||
## Status
|
||||
Etap 1 — w budowie. Implementacja powstaje ściśle według `docs/SPEC.md`.
|
||||
74
docs/LEXICON.md
Normal file
74
docs/LEXICON.md
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# LEXICON — zweryfikowany leksykon polski
|
||||
|
||||
Te formy są **ręcznie zweryfikowane** i stanowią jedyne źródło powierzchniowych form
|
||||
słów. Implementacja przepisuje je **dokładnie** (z polskimi znakami), bez zmian.
|
||||
Rozszerzanie list — patrz sekcja na końcu.
|
||||
|
||||
## OBJECTS (przedmioty)
|
||||
`gender`: `m` = męski nieżywotny, `f` = żeński, `n` = nijaki.
|
||||
`acc` = forma w **bierniku** (dopełnienie czasownika: „połóż **acc**").
|
||||
|
||||
| id | nom (mianownik) | acc (biernik) | gender |
|
||||
|---|---|---|---|
|
||||
| jablko | jabłko | jabłko | n |
|
||||
| kubek | kubek | kubek | m |
|
||||
| lyzka | łyżka | łyżkę | f |
|
||||
| ksiazka | książka | książkę | f |
|
||||
| dlugopis | długopis | długopis | m |
|
||||
| klucz | klucz | klucz | m |
|
||||
| pilka | piłka | piłkę | f |
|
||||
| butelka | butelka | butelkę | f |
|
||||
| talerz | talerz | talerz | m |
|
||||
| banan | banan | banan | m |
|
||||
|
||||
## COLORS (kolory)
|
||||
Forma przymiotnika w **bierniku**, zależna od rodzaju rzeczownika.
|
||||
|
||||
| id | m | f | n |
|
||||
|---|---|---|---|
|
||||
| czerwony | czerwony | czerwoną | czerwone |
|
||||
| zielony | zielony | zieloną | zielone |
|
||||
| niebieski | niebieski | niebieską | niebieskie |
|
||||
| zolty | żółty | żółtą | żółte |
|
||||
| bialy | biały | białą | białe |
|
||||
| czarny | czarny | czarną | czarne |
|
||||
|
||||
## LOCATIONS (miejsca)
|
||||
Gotowa fraza „**na** + miejscownik". Przechowywana w całości — bez odmiany w kodzie.
|
||||
|
||||
| id | phrase |
|
||||
|---|---|
|
||||
| stol | na stole |
|
||||
| krzeslo | na krześle |
|
||||
| polka | na półce |
|
||||
| podloga | na podłodze |
|
||||
| biurko | na biurku |
|
||||
| parapet | na parapecie |
|
||||
|
||||
## VERBS (czasowniki)
|
||||
Tryb rozkazujący, biorą biernik, neutralne semantycznie dla powyższych obiektów.
|
||||
|
||||
| id | forma (wielką literą) |
|
||||
|---|---|
|
||||
| poloz | Połóż |
|
||||
| umiesc | Umieść |
|
||||
|
||||
W kolejnych klauzulach czasownik pisany małą literą (np. `umieść`).
|
||||
|
||||
## Notatki gramatyczne
|
||||
- Po czasownikach `połóż`/`umieść` dopełnienie jest w **bierniku**.
|
||||
- męski nieżywotny i nijaki: biernik = mianownik (`kubek`, `jabłko`),
|
||||
- żeński zwykle `-a → -ę` (`łyżka → łyżkę`).
|
||||
- Przymiotnik **zgadza się** z rzeczownikiem co do rodzaju i przypadka
|
||||
(`czerwone jabłko`, `czerwoną łyżkę`, `czerwony kubek`).
|
||||
- Miejsce: konstrukcja `na` + **miejscownik** (`na stole`, `na krześle`).
|
||||
|
||||
## Rozszerzanie
|
||||
Dodając wpis, podaj poprawne formy ręcznie (nie polegaj na automatycznej odmianie):
|
||||
- OBJECTS: `acc` i `gender`,
|
||||
- COLORS: trzy formy biernika (m/f/n),
|
||||
- LOCATIONS: pełna fraza „na + miejscownik",
|
||||
- VERBS: forma rozkazująca biorąca biernik, pasująca do wszystkich obiektów.
|
||||
|
||||
Zalecenie: dobór słów i progresję trudności powinien zatwierdzić logopeda lub
|
||||
neurologopeda.
|
||||
36
docs/ROADMAP.md
Normal file
36
docs/ROADMAP.md
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
# ROADMAP
|
||||
|
||||
## Etap 1 — Rdzeń na PC (obecny)
|
||||
Generowanie poprawnych poleceń + Piper TTS, CLI, testy. Bez STT, bez VR.
|
||||
Szczegóły: `docs/SPEC.md`.
|
||||
|
||||
## Etap 2 — Tło mieszanej rzeczywistości (Meta Quest 3)
|
||||
Passthrough + proste obiekty (np. stół, jabłko). Generator z etapu 1 przenoszony
|
||||
bez zmian (sama logika treści jest niezależna od platformy). UI: natywny OpenXR.
|
||||
|
||||
## Etap 3 — Interakcja i ocena
|
||||
STT (rozpoznanie/repetycja), ocena wykonania polecenia (czy pacjent wskazał/położył
|
||||
właściwy obiekt), sesje i statystyki postępu.
|
||||
|
||||
## Ograniczenia platformy docelowej (do etapu 2/3)
|
||||
Wartości ustalone wcześniej; do zweryfikowania na sprzęcie.
|
||||
|
||||
| Parametr | Wartość |
|
||||
|---|---|
|
||||
| Limit pamięci aplikacji (Quest 3, PSS) | ~5,75 GiB (twardy, narzucony przez system) |
|
||||
| CPU | Snapdragon XR2 Gen 2: 2 rdzenie performance + 4 efficiency (brak „prime") |
|
||||
| Maks. CPU level | 6 |
|
||||
| Tryb dual-core | niewspierany na Quest 3 |
|
||||
| GPU | Adreno 740 |
|
||||
| Inferencja LLM | CPU-only (backend OpenCL llama.cpp nie jest zwalidowany na Adreno 740; GPU obciążony renderowaniem) |
|
||||
| Model LLM (cel) | Qwen2.5 1.5B Q4 (GGUF, llama.cpp) |
|
||||
| STT (cel) | whisper.cpp Tiny |
|
||||
| TTS | Piper (głos polski) |
|
||||
| Tryb | 100% offline |
|
||||
|
||||
Konsekwencja dla treści: leksykonowo-szablonowe generowanie z etapu 1 jest tu
|
||||
przewagą — gwarantuje poprawność niezależnie od rozmiaru modelu na urządzeniu.
|
||||
|
||||
## Dystrybucja
|
||||
Cel: sideload / App Lab. Pełne wydanie w sklepie nie jest zakładane (stałe użycie
|
||||
mikrofonu w etapie 3, lokalna inferencja, charakter asystujący).
|
||||
127
docs/SPEC.md
Normal file
127
docs/SPEC.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# SPEC — Etap 1 (PC, offline)
|
||||
|
||||
Specyfikacja jest **wiążącym celem buildu**. Implementacja ma być z nią zgodna.
|
||||
|
||||
## 1. Cel i zakres
|
||||
Generować proste polskie polecenia typu *„Połóż jabłko na stole"* i opcjonalnie je
|
||||
wypowiadać (Piper TTS). Typ ćwiczenia: **wykonywanie poleceń** (rozumienie ze słuchu).
|
||||
|
||||
W zakresie etapu 1:
|
||||
- generowanie poleceń (losowo lub przez LLM),
|
||||
- wypowiadanie ich (TTS, opcjonalne),
|
||||
- interfejs CLI.
|
||||
|
||||
Poza zakresem etapu 1: STT, ocena wykonania, VR/MR, GUI.
|
||||
|
||||
## 2. Zasady naczelne
|
||||
1. **Poprawność fleksji jest krytyczna.** Wszystkie powierzchniowe formy słów
|
||||
pochodzą wyłącznie z `docs/LEXICON.md`. Nie wolno generować ani modyfikować odmian.
|
||||
2. **LLM zwraca tylko identyfikatory**, nigdy polski tekst. Tekst składa kod
|
||||
z leksykonu. Dzięki temu mały model nie może zepsuć gramatyki.
|
||||
3. **Offline.** Brak zależności sieciowych w czasie działania poza opcjonalnym,
|
||||
lokalnym serwerem LLM (localhost).
|
||||
4. **Defensywność TTS.** Brak Pipera lub głosu nie przerywa działania — demo działa
|
||||
wtedy w trybie tekstowym.
|
||||
|
||||
## 3. Stos i układ plików
|
||||
Python 3.10+. Rdzeń i klient LLM korzystają wyłącznie z biblioteki standardowej
|
||||
(LLM przez `urllib`, bez `requests`). Piper jest opcjonalny.
|
||||
|
||||
```
|
||||
ipin-vr/
|
||||
README.md
|
||||
requirements.txt # tylko opcjonalne: piper-tts; rdzeń = stdlib
|
||||
.gitignore # venv, __pycache__, *.wav, *.onnx, *.onnx.json
|
||||
docs/
|
||||
ipin_vr/
|
||||
__init__.py
|
||||
__main__.py # uruchamia cli.main()
|
||||
lexicon.py # dane z docs/LEXICON.md (przepisane DOKŁADNIE)
|
||||
generator.py # Clause, Command, render(), random_command()
|
||||
llm.py # generator oparty na llama.cpp (opcjonalny)
|
||||
tts.py # Piper przez subprocess (opcjonalny, defensywny)
|
||||
cli.py # argparse + pętla główna
|
||||
tests/
|
||||
test_generator.py
|
||||
```
|
||||
Uruchamianie: `python -m ipin_vr [opcje]`.
|
||||
|
||||
## 4. Model danych
|
||||
- `Clause(verb_id, object_id, location_id, color_id: str | None)`
|
||||
- `Command(clauses: list[Clause], level: int)`
|
||||
|
||||
Identyfikatory muszą istnieć w leksykonie; walidacja przy tworzeniu z danych LLM.
|
||||
|
||||
## 5. Reguły renderowania
|
||||
Klauzula = `Czasownik` + (`przymiotnik[rodzaj obiektu]` + spacja, jeśli kolor) +
|
||||
`obiekt.acc` + spacja + `miejsce.fraza`.
|
||||
|
||||
- Czasownik w **pierwszej** klauzuli pisany wielką literą; w kolejnych — małą.
|
||||
- Klauzule łączone separatorem `" i "`.
|
||||
- Całość zakończona kropką.
|
||||
- Poziom 1: jedna klauzula, bez koloru.
|
||||
- Poziom 2: jedna klauzula, z kolorem.
|
||||
- Poziom 3: dwie klauzule o **różnych** obiektach; kolor opcjonalny w każdej.
|
||||
|
||||
Przykłady poprawnych wyników:
|
||||
- `Połóż jabłko na stole.`
|
||||
- `Połóż żółtą piłkę na parapecie.`
|
||||
- `Umieść niebieskie jabłko na stole.`
|
||||
- `Połóż zieloną książkę na półce i umieść klucz na biurku.`
|
||||
|
||||
## 6. Generator losowy
|
||||
`random_command(level)` losuje czasownik, obiekt, miejsce (oraz kolor zależnie od
|
||||
poziomu). Dla poziomu 3 gwarantuje różne obiekty w obu klauzulach.
|
||||
|
||||
## 7. Generator LLM (opcjonalny)
|
||||
Klient POST na endpoint zgodny z OpenAI (`/v1/chat/completions`,
|
||||
domyślnie `http://localhost:8080/v1/chat/completions`).
|
||||
|
||||
System prompt wymusza zwrot **wyłącznie** obiektu JSON:
|
||||
```json
|
||||
{"clauses":[{"verb":"<id>","object":"<id>","location":"<id>","color":"<id|null>"}],"level":1}
|
||||
```
|
||||
Przekaż modelowi dozwolone listy identyfikatorów (z leksykonu). Po odebraniu:
|
||||
1. wyciągnij JSON, sparsuj,
|
||||
2. **zwaliduj** każdy identyfikator względem leksykonu,
|
||||
3. renderuj z leksykonu.
|
||||
|
||||
Każdy błąd (timeout, brak serwera, niepoprawny JSON, nieznany identyfikator) ⇒
|
||||
**fallback** na `random_command(level)`. Tekst z LLM nigdy nie trafia na wyjście.
|
||||
|
||||
## 8. TTS (opcjonalny, defensywny)
|
||||
Piper przez `subprocess`: `piper --model <onnx> --output_file <wav>`, tekst na stdin.
|
||||
Odtwarzanie zależnie od OS: `aplay` (Linux), `afplay` (macOS), `winsound` (Windows).
|
||||
Brak Pipera/głosu/odtwarzacza ⇒ wypisz `[TTS off: <powód>]` i kontynuuj.
|
||||
|
||||
## 9. CLI
|
||||
| Flaga | Domyślnie | Opis |
|
||||
|---|---|---|
|
||||
| `--level {1,2,3}` | 1 | poziom trudności |
|
||||
| `--count N` | 5 | liczba poleceń |
|
||||
| `--delay S` | 4.0 | pauza między poleceniami (s) |
|
||||
| `--voice PATH` | — | ścieżka do modelu Piper `.onnx` |
|
||||
| `--no-audio` | — | wyłącza TTS |
|
||||
| `--llm` | — | użyj LLM do wyboru poleceń |
|
||||
| `--llm-endpoint URL` | localhost:8080 | endpoint llama.cpp |
|
||||
| `--llm-model NAME` | `local` | nazwa modelu |
|
||||
| `--seed N` | — | deterministyczny losowy generator |
|
||||
|
||||
Każde polecenie wypisywane na stdout (numerowane) i — jeśli włączone audio — wypowiadane.
|
||||
|
||||
## 10. Testy (pytest)
|
||||
`tests/test_generator.py` sprawdza `render()` dla ustalonych speców względem
|
||||
oczekiwanych stringów. Pokrycie obowiązkowe:
|
||||
- kolor + rzeczownik dla każdego rodzaju (m, f, n),
|
||||
- poprawny miejscownik miejsca,
|
||||
- łączenie dwóch klauzul (poziom 3),
|
||||
- kapitalizacja: pierwsza klauzula wielką, druga małą literą.
|
||||
|
||||
## 11. Zależności
|
||||
Rdzeń, generator i klient LLM: tylko biblioteka standardowa. `requirements.txt`
|
||||
zawiera jedynie opcjonalne `piper-tts`. README opisuje pobranie głosu polskiego.
|
||||
|
||||
## 12. Definition of done
|
||||
- `pytest` przechodzi w całości.
|
||||
- `python -m ipin_vr --level 3 --count 6 --no-audio` wypisuje 6 poprawnych poleceń.
|
||||
- README zawiera działający szybki start (tryb bez audio) i instrukcje audio/LLM.
|
||||
Loading…
Reference in a new issue