Download RSS_AI_Engine/main.py from Biraboro/RRas-ai-engine: direct link, hf CLI and curl.
- Browser
- Download file 5.84 kB
-
https://huggingface.co/Biraboro/RRas-ai-engine/resolve/main/RSS_AI_Engine/main.py
- Command line
-
hf download hf://Biraboro/RRas-ai-engine/RSS_AI_Engine/main.py
-
curl -L -o main.py https://huggingface.co/Biraboro/RRas-ai-engine/resolve/main/RSS_AI_Engine/main.py
5.84 kB
| #!/usr/bin/env python3 | |
| """RSS AI Engine - application entry point. | |
| python RSS_AI_Engine/main.py --mode clean stream + clean data only | |
| python RSS_AI_Engine/main.py --mode pretrain Stage-1 continual pre-training only | |
| python RSS_AI_Engine/main.py --mode finetune Stage-2 rational SFT only | |
| python RSS_AI_Engine/main.py --mode train_all purge -> fresh HF model -> clean -> pretrain -> finetune -> upload | |
| python RSS_AI_Engine/main.py --mode serve load the trained model -> Telegram bot or CLI chat | |
| Extras: --fresh-model --upload-only --skip-upload --limit 150|full --tier 1|2|3 --threads N | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import importlib.util | |
| import os | |
| import signal | |
| import subprocess | |
| import sys | |
| from datetime import datetime | |
| from pathlib import Path | |
| # Set native tokenizer/OpenMP limits BEFORE importing torch/transformers/tokenizers. | |
| os.environ["TOKENIZERS_PARALLELISM"] = "false" | |
| os.environ["OMP_NUM_THREADS"] = "2" | |
| os.environ["MKL_NUM_THREADS"] = "2" | |
| ROOT = Path(__file__).resolve().parent | |
| ENV_TEMPLATE = """HF_TOKEN="hf_PUT_YOUR_TOKEN_HERE" | |
| TELEGRAM_BOT_TOKEN="" | |
| TELEGRAM_CHAT_ID="" | |
| BASE_MODEL_REPO="Qwen/Qwen2.5-0.5B-Instruct" | |
| OUTPUT_HF_REPO="Biraboro/rss-ai-trained" | |
| SOURCE_REPOS='[{"repo": "Biraboro/Youtop-trenscprit", "limit": 150}]' | |
| LOCAL_CHAT_FILE="./chat.jsonl" | |
| JSON_PRETRAIN_QUOTA="0.15" | |
| PRETRAIN_CONV_RATIO="0.25" | |
| PURGE_OLD_MODEL_ON_START="true" | |
| EXTRA_BLOCKED_EXTENSIONS="" | |
| """ | |
| # (import name, pip name) | |
| REQUIRED = [("torch", "torch"), ("transformers", "transformers"), ("accelerate", "accelerate"), | |
| ("peft", "peft"), ("datasets", "datasets"), ("huggingface_hub", "huggingface_hub"), | |
| ("safetensors", "safetensors"), ("psutil", "psutil"), ("dotenv", "python-dotenv"), | |
| ("requests", "requests")] | |
| def ensure_env_file() -> None: | |
| env = ROOT / ".env" | |
| if not env.exists(): | |
| env.write_text(ENV_TEMPLATE, encoding="utf-8") | |
| print(f"[Setup] created {env} - put your HF_TOKEN (write access) in it before uploading") | |
| def _pip(package: str) -> None: | |
| base = [sys.executable, "-m", "pip", "install", "-q", package] | |
| if subprocess.call(base) != 0: | |
| # PEP 668 "externally managed" interpreters (Debian/Ubuntu system python) need this flag | |
| subprocess.check_call(base + ["--break-system-packages"]) | |
| def _cuda_present() -> bool: | |
| try: | |
| import torch | |
| return bool(torch.cuda.is_available()) | |
| except Exception: | |
| return False | |
| def ensure_dependencies() -> None: | |
| missing = [pip for mod, pip in REQUIRED if importlib.util.find_spec(mod) is None] | |
| for package in missing: | |
| print(f"[Setup] installing {package} ...") | |
| _pip(package) | |
| if _cuda_present() and importlib.util.find_spec("bitsandbytes") is None: | |
| print("[Setup] CUDA detected -> installing bitsandbytes (4-bit NF4)") | |
| try: | |
| _pip("bitsandbytes") | |
| except Exception as exc: | |
| print(f"[Setup] bitsandbytes install failed ({exc}); GPU tier will run without 4-bit") | |
| if not missing: | |
| print("[Setup] all dependencies present") | |
| def parse_args(argv=None) -> argparse.Namespace: | |
| parser = argparse.ArgumentParser(description="RSS AI Engine", formatter_class=argparse.RawTextHelpFormatter) | |
| parser.add_argument("--mode", choices=["clean", "pretrain", "finetune", "train_all", "serve"], default="serve", | |
| help="clean | pretrain | finetune | train_all | serve (default: serve)") | |
| parser.add_argument("--fresh-model", action="store_true", | |
| help="purge old checkpoints/offload files and download the base model again") | |
| parser.add_argument("--upload-only", action="store_true", help="only upload ./trained_model to OUTPUT_HF_REPO") | |
| parser.add_argument("--skip-upload", action="store_true", help="train_all without the final upload") | |
| parser.add_argument("--limit", default=None, help="override every repo limit: a number or 'full'") | |
| parser.add_argument("--tier", type=int, choices=[1, 2, 3], default=None, help="force execution tier") | |
| parser.add_argument("--threads", type=int, default=None, help="CPU threads for torch") | |
| parser.add_argument("--no-install", action="store_true", help="do not auto-install missing dependencies") | |
| return parser.parse_args(argv) | |
| def _handle_sigterm(signum, _frame) -> None: | |
| stamp = datetime.now().astimezone().isoformat(timespec="seconds") | |
| print(f"\n[Runtime] received SIGTERM ({signum}) at {stamp}; " | |
| "external supervisor/timeout or user termination is possible; sender is not identifiable here.", | |
| flush=True) | |
| raise SystemExit(128 + int(signum)) | |
| def main(argv=None) -> int: | |
| try: | |
| signal.signal(signal.SIGTERM, _handle_sigterm) | |
| except (AttributeError, ValueError): | |
| pass | |
| args = parse_args(argv) | |
| ensure_env_file() | |
| if not args.no_install: | |
| ensure_dependencies() | |
| if str(ROOT) not in sys.path: | |
| sys.path.insert(0, str(ROOT)) | |
| try: | |
| import torch | |
| torch.set_num_threads(2) | |
| try: | |
| torch.set_num_interop_threads(2) | |
| except RuntimeError: | |
| # Inter-op pool may already be initialised by an embedding host. | |
| pass | |
| print(f"[Runtime] torch threads={torch.get_num_threads()} interop={torch.get_num_interop_threads()}", | |
| flush=True) | |
| except ImportError: | |
| pass | |
| from Integration_Layer import engine_orchestrator as orchestrator | |
| cfg = orchestrator.build_config(args) | |
| try: | |
| orchestrator.run(args.mode, cfg, args) | |
| except FileNotFoundError as exc: | |
| print(f"\n[RSS] {exc}") | |
| return 2 | |
| except KeyboardInterrupt: | |
| print("\n[RSS] interrupted") | |
| return 130 | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |