Separate package for serving DEEP-Dari, labeling real public YouTube comments, and browsing results in a bilingual EN / FA (RTL) dashboard. Training code stays under scripts/ and augmentations/.
From the repo root (after the main project requirements are installed):
pip install -r deployment/requirements.txtSet a YouTube Data API v3 key:
# Linux / macOS / DGX
export YOUTUBE_API_KEY=your-key
# Windows PowerShell
$env:YOUTUBE_API_KEY = "your-key"Model resolution order for the interactive /api/predict singleton (first existing checkpoint wins):
outputs/ablation/A4Models/parsbert_emotion_incrementalModels/parsbert_emotion
Override with --model-path or DEPLOYMENT_MODEL_PATH.
Batch jobs (New job UI / CLI) can select an ablation checkpoint by id:
model_id |
Primary path | Automatic fallbacks |
|---|---|---|
A4 (default) |
outputs/ablation/A4 |
A4/seed_42/ (multi-seed); else Models/parsbert_emotion_incremental if trained on allAug |
A0 |
outputs/ablation/A0 |
— |
A1 |
outputs/ablation/A1 |
Legacy outputs/full_8label_aug_* whose training_metadata.json uses Combined_Labeled_Dataset_with_fearAug.csv (highest checkpoint-*) |
Also accepts config.json under checkpoint-<step>/ inside a run folder.
python -m deployment.youtube_batch --video-id VIDEO --model-id A0 --max-comments 100GET /api/models lists availability after these lookups. Unavailable options are disabled in the dashboard. No manual symlinks required when the legacy Fear-aug or multi-seed layouts are present.
Pipeline:
- Clean — strip URLs,
@mentions, emojis; unify ي/ی and ك/ک - Gate — drop comments that are empty, emoji-only, too short (< 4 tokens), or mostly non-Persian/Dari (Persian-script ratio < 0.5) →
Excluded(no model call) - Predict — ParsBERT on remaining text
- Abstain — if confidence <
--min-confidence(default 0.50) →Others
So Others = model unsure on usable Dari/Persian, not emoji/Latin noise.
summary.json reports both views:
exclusion_rate,n_excludedothers_rate_among_usable,label_counts_usablelabel_counts_all(includes Excluded)
Dashboard Run detail has a defense toggle: Usable only (default) vs All comments.
Refresh old runs (remap legacy Others+unusable_text → Excluded):
python -m deployment.reaggregate
python -m deployment.reaggregate --run-id youtube_batch_20260727T035253Zpython -m deployment.youtube_batch --video-id VIDEO_ID --max-comments 500
python -m deployment.youtube_batch --channel-id CHANNEL_ID --max-videos 5 --max-comments 1000Video and channel arguments accept raw IDs or full YouTube links. The CLI and New Job form normalize them the same way:
| Paste | Resolved to |
|---|---|
https://www.youtube.com/watch?v=…, youtu.be/…, /shorts/…, /embed/… |
11-char video id |
| Bare 11-char id | unchanged |
https://www.youtube.com/channel/UC… or bare UC… |
channel id |
https://www.youtube.com/@Handle or @Handle |
UC… via YouTube API (channels.list(forHandle=…)) |
/c/… or /user/… |
best-effort resolve via API search |
Examples:
python -m deployment.youtube_batch --video-id 'https://www.youtube.com/watch?v=16e75OffBTA'
python -m deployment.youtube_batch --channel-id '@SomeHandle' --max-videos 5Invalid pastes return a clear error before the job starts.
Outputs: outputs/deployment/youtube_batch_<timestamp>/
Build the React UI once (needs Node.js 18+):
cd deployment/dashboard
npm install
npm run build
cd ../..Run API + dashboard together:
export YOUTUBE_API_KEY=your-key # required to start jobs from the UI
uvicorn deployment.api:app --host 0.0.0.0 --port 8000Open http://SERVER:8000
| Page | Features |
|---|---|
| Runs | Past batch folders with KPIs |
| Run detail | Emotion charts, filters, RTL comment table, Fear/Anger review marks |
| New job | Start video/channel labeling; live logs |
| Global queue | review_queue.jsonl |
Language toggle EN / FA in the header (Persian uses Vazirmatn + RTL).
Terminal 1:
uvicorn deployment.api:app --reload --port 8000Terminal 2:
cd deployment/dashboard && npm run devOpen http://127.0.0.1:5173 (Vite proxies /api → 8000).
GET /api/health— model + YouTube key statusGET /api/runs— list batchesGET /api/runs/{id}— summaryGET /api/runs/{id}/comments— paginated filtersGET /api/runs/{id}/review/POST— review annotationsPOST /api/jobs— start batch jobGET /api/jobs/{id}— job status + logsPOST /api/predict— single/batch text predict
python -m deployment.youtube_monitor --video-id LIVE_VIDEO_ID --poll-seconds 20Public comments only, minimal storage, research/demo use. Alerts notify a human review queue — no auto-action.