Test / Readme.md
Hfzune's picture
Update Readme.md
d645ec8 verified
|
Raw History Blame Contribute Delete
11.2 kB
---
title: DeepSeek-OCR Full-Page CSV
emoji: 📄
colorFrom: blue
colorTo: green
sdk: gradio
sdk_version: 5.49.1
python_version: "3.10"
app_file: app.py
pinned: false
---
# 🤖 Qwen Telegram Bot
A Telegram bot backed by **Qwen2.5-1.5B-Instruct** running on Hugging Face **ZeroGPU** (free tier), with streaming responses, per-user token access, and a full admin panel for monitoring conversations, managing tokens, and exporting logs.
Built to survive the ZeroGPU free tier: no Docker, no external servers, no paid APIs.
---
## ✨ Features
### For users (Telegram)
- 🔒 **Token-gated access** — only users with an admin-issued token can chat
- ⚡ **Streaming replies** — see the response as it's generated
- 💻 **Proper code formatting** — Markdown → Telegram HTML, with language-tagged code boxes
- 📜 **Conversation memory** — rolling window of past turns (configurable)
- 🧹 `/reset` to clear the current chat's memory
- 📊 `/stats` to see your own usage
### For admin (web panel)
- 🔐 **Password-gated** admin tab inside the Gradio UI
- 📊 **Dashboard** — users, turns, GPU quota consumed today
- 👥 **User management** — view, revoke, delete users
- 💬 **Conversation logs** — filter by user, search, view full history
- 📤 **Export logs** — JSON / CSV / Markdown, full conversation dump
- 🎟️ **Token management** — generate individually, bulk-generate, revoke, reassign
- ⚙️ **Runtime settings** — system prompt, temperature, top_p, max tokens, conversation window, daily limit
- 🩺 **Health** — recent GPU calls, latency, quota status
---
## 🏗️ Architecture
```
Telegram ──webhook──▶ HF Space (Gradio SDK, ZeroGPU)
│
├── Gradio UI (Status + Admin tabs)
├── /webhook → bot logic
├── /health → keep-alive target
├── /admin/* → admin API
│
├── SQLite (/data/bot.db) users, tokens, convs, gpu_log
└── @spaces.GPU generate_stream()
│
▼
Qwen2.5-1.5B on Blackwell GPU (48 GB slice)
```
- **Single Gradio app** — admin panel is a tab, not a separate mount (this avoids the 33 s Node SSR startup hang)
- **Route injection at index 0** — `/webhook` and `/health` take priority over Gradio's catch-all
- **Model loaded at module scope** — ZeroGPU "packs" weights to disk; each `@spaces.GPU` call attaches the GPU
- **All persistence in the main process** — SQLite in WAL mode; conversation state survives GPU worker forks
---
## 🚀 Deployment
### 1. Create the Space
- Go to https://huggingface.co/new-space
- **SDK:** Gradio
- **Hardware:** ZeroGPU (free tier is fine)
- **Visibility:** Private or Public — your choice
### 2. Get a Telegram bot token
- Message [@BotFather](https://t.me/BotFather) → `/newbot`
- Save the token (looks like `123456789:ABC...`)
### 3. Configure Space secrets
Settings → **Variables and secrets** → add:
| Name | Required | Value |
|---|---|---|
| `TELEGRAM_BOT_TOKEN` | ✅ | Bot token from BotFather |
| `PUBLIC_URL` | ✅ | `https://<user>-<space>.hf.space` (your Space URL, no trailing slash) |
| `TELEGRAM_WEBHOOK_SECRET` | ⭐ recommended | Random string — Telegram will send it in `X-Telegram-Bot-Api-Secret-Token` |
| `ADMIN_PASSWORD` | ⭐ recommended | Password for the web admin panel. **Default: `tom123`** — change it! |
| `ADMIN_TELEGRAM_IDS` | optional | Comma-separated Telegram IDs allowed to use `/admin` bot command |
| `MODEL_ID` | optional | Override model. Default: `thirdeyeai/Qwen2.5-1.5B-Instruct-uncensored` |
| `TELEGRAM_PROXY` | optional | Cloudflare Worker URL if `api.telegram.org` is blocked in your Space's region |
### 4. Upload the files
Push the repo (git, web upload, or HF CLI). Structure:
```
.
├── app.py
├── requirements.txt
├── README.md
├── admin/
│ ├── __init__.py
│ ├── auth.py
│ ├── exports.py
│ └── panel.py
├── bot/
│ ├── __init__.py
│ ├── onboarding.py
│ ├── streaming.py
│ ├── telegram_api.py
│ └── webhook.py
├── db/
│ ├── __init__.py
│ ├── init.py
│ ├── models.py
│ └── schema.sql
├── model/
│ ├── __init__.py
│ └── qwen.py
└── utils/
├── __init__.py
├── audit.py
├── health.py
└── quota.py
```
### 5. Wait for the build
First boot downloads ~3 GB of model weights. Watch the **Logs** tab for:
```
Loading weights: 100%|██████████|
db: DB initialised at /data/bot.db
app: Launching Gradio...
app: Boot complete. Blocking.
```
### 6. Register the webhook
The app auto-registers on boot if `PUBLIC_URL` is set. Verify with:
```
https://api.telegram.org/bot<TOKEN>/getWebhookInfo
```
You should see your Space URL and no `last_error_message`.
### 7. Keep it awake
ZeroGPU Spaces sleep after idle. Set up an **external** pinger:
**Option A — cron-job.org** (free, 5 min)
- URL: `https://<user>-<space>.hf.space/health`
- Interval: every 5 minutes
**Option B — GitHub Actions**
```yaml
name: keepalive
on:
schedule: [{cron: "*/5 * * * *"}]
jobs:
ping:
runs-on: ubuntu-latest
steps:
- run: curl -fsS https://<user>-<space>.hf.space/health || true
```
⚠️ **Internal heartbeats don't count.** The container must receive external traffic.
### 8. First admin login
- Visit `https://<user>-<space>.hf.space/`
- Click **🔐 Admin Panel** tab
- Enter `tom123` (or your `ADMIN_PASSWORD`)
### 9. Issue your first token
- Admin → **🎟️ Tokens** tab → **Generate batch (1)**
- Copy the token
- In Telegram, DM your bot: `/token <that-token>`
- You'll see **Token accepted.** — you can now chat
---
## 💬 Telegram Commands
| Command | Description |
|---|---|
| `/start` | Welcome / onboarding |
| `/token VALUE` | Submit or replace your access token |
| `/reset` | Clear this chat's conversation memory |
| `/stats` | Show your usage stats |
| `/help` | List commands |
| `/admin` | (Admin IDs only) — reminder of the web admin URL |
---
## 🌐 HTTP Endpoints
| Method | Path | Purpose |
|---|---|---|
| GET | `/health` | Keep-alive target — returns JSON with uptime |
| POST | `/webhook` | Telegram updates (validated by secret header) |
| GET | `/admin` | Redirects to `/` (admin is a tab) |
| GET | `/admin/quota` | JSON quota snapshot |
| POST | `/admin/boot_webhook` | Re-register the Telegram webhook |
---
## 🗄️ Database Schema
All tables live in `/data/bot.db` (persistent across Space restarts).
| Table | Purpose |
|---|---|
| `users` | Telegram user records, `is_active` flag, token binding |
| `tokens` | Issued tokens with `assigned_to`, `turns_used`, `last_used` |
| `conversations` | Every user/assistant message with timestamps and latency |
| `admin_audit` | Admin actions (boot, generate, revoke) |
| `gpu_log` | Every GPU call with duration — used for quota tracking |
| `settings` | Runtime-configurable key/value pairs |
---
## ⚙️ Runtime Settings (Admin → Settings tab)
| Setting | Default | Notes |
|---|---|---|
| `system_prompt` | "You are a helpful assistant." | Change this to steer the model's behavior |
| `conversation_window` | 6 turns | How many past turns are sent as context |
| `max_new_tokens` | 1024 | Hard cap on reply length |
| `temperature` | 0.7 | 0 = deterministic, 1.0 = creative |
| `top_p` | 0.9 | Nucleus sampling cutoff |
| `daily_turn_limit` | 100 | Max turns per user per day |
Changes apply **immediately** to the next message — no restart needed.
---
## 📤 Export Formats
Admin → Conversations → Export:
- **JSON** — full nested structure, one object per user with all their turns
- **CSV** — flat, one row per message (best for spreadsheets)
- **Markdown** — human-readable transcript per user
Each message row includes timestamp, role, content, `latency_ms`, `gpu_time_ms`.
---
## 🧠 Free-Tier Reality Check
ZeroGPU free tier gives roughly **300 seconds of GPU time per day**. A typical chat turn on a 1.5B model at BF16 costs **2–5 seconds**. That works out to roughly **60–100 turns per day** across all users.
Practical implications:
- **Admin → Dashboard** shows `GPU seconds used today / 300`
- The bot refuses new generations when usage exceeds ~280 s (safety margin)
- **Keep conversations short** — larger `conversation_window` = more tokens = more GPU time
- If you need more headroom, either:
- Reduce `max_new_tokens`
- Reduce `conversation_window`
- Upgrade to HF PRO (~25× more GPU quota)
---
## 🛠️ Troubleshooting
### Bot replies to `/start` but ignores messages
Check `user_has_valid_token` — the user must have redeemed a token via `/token`.
### `Bad Request: unsupported parse_mode`
Only happens if you modified `telegram_api.py`. The fix: never send `parse_mode: null` — omit the key entirely for plain text.
### Messages are cut off mid-sentence
Increase `max_new_tokens` in Admin → Settings. Or ask for shorter responses.
### Code blocks show as raw text
Means the model produced HTML that our converter didn't recognize. Check Admin → Conversations to see the raw output and open an issue with the exact text.
### Space sleeps and cold-starts take 30 s
External pinger isn't running. Check cron-job.org logs. Remember: only **external** traffic resets the idle timer.
### `Bad Request: message is too long`
Shouldn't happen — we auto-split at 3900 chars. If you see it, a single HTML entity is likely breaking the length math; open an issue.
---
## ⚠️ Security Notes
- **Never paste your `TELEGRAM_BOT_TOKEN` publicly.** If leaked, revoke it via BotFather (`/revoke` → pick bot).
- **Change `ADMIN_PASSWORD`** from the default `tom123` before going public.
- **Set `TELEGRAM_WEBHOOK_SECRET`** — otherwise anyone who guesses your Space URL can POST fake updates.
- The bot accepts **only text** messages. Photos, voice, and files are rejected — this is by design.
- Conversation content is stored in plain SQLite. Don't paste secrets into the chat.
---
## 📋 Project Structure Notes
- **`app.py`** — entry point. HfFolder shim → Gradio build → launch → route injection → block.
- **`model/qwen.py`** — the only file with `@spaces.GPU`. Everything else runs on CPU.
- **`bot/telegram_api.py`** — all Telegram HTTP calls, markdown→HTML conversion, and message chunking.
- **`db/models.py`** — all SQL. No ORM, just explicit queries.
- **`admin/panel.py`** — Gradio Blocks built *inside* the main app context (no second mount).
---
## 📜 License
Personal project. Do whatever you want with it.
---
## 🙏 Credits
- Model: [thirdeyeai/Qwen2.5-1.5B-Instruct-uncensored](https://huggingface.co/thirdeyeai/Qwen2.5-1.5B-Instruct-uncensored)
- ZeroGPU: [Hugging Face Spaces](https://huggingface.co/docs/hub/spaces-gpus)
- Gradio: [gradio.app](https://gradio.app)