mirror of
https://github.com/azaion/ai-training.git
synced 2026-04-22 10:46:35 +00:00
Refactor constants management to use Pydantic BaseModel for configuration
- Replaced module-level path variables in constants.py with a structured Pydantic Config class. - Updated all relevant modules (train.py, augmentation.py, exports.py, dataset-visualiser.py, manual_run.py) to access paths through the new config structure. - Fixed bugs related to image processing and model saving. - Enhanced test infrastructure to accommodate the new configuration approach. This refactor improves code maintainability and clarity by centralizing configuration management.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# Module: annotation-queue/annotation_queue_dto
|
||||
|
||||
## Purpose
|
||||
Data transfer objects for the annotation queue consumer. Defines message types for annotation CRUD events received from a RabbitMQ Streams queue.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### AnnotationClass (local copy)
|
||||
Same as dto/annotationClass but reads `classes.json` from current working directory and adds `opencv_color` BGR field.
|
||||
|
||||
### AnnotationStatus (Enum)
|
||||
| Member | Value |
|
||||
|--------|-------|
|
||||
| Created | 10 |
|
||||
| Edited | 20 |
|
||||
| Validated | 30 |
|
||||
| Deleted | 40 |
|
||||
|
||||
### SourceEnum (Enum)
|
||||
| Member | Value |
|
||||
|--------|-------|
|
||||
| AI | 0 |
|
||||
| Manual | 1 |
|
||||
|
||||
### RoleEnum (Enum)
|
||||
| Member | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| Operator | 10 | Regular annotator |
|
||||
| Validator | 20 | Annotation validator |
|
||||
| CompanionPC | 30 | Companion device |
|
||||
| Admin | 40 | Administrator |
|
||||
| ApiAdmin | 1000 | API-level admin |
|
||||
|
||||
`RoleEnum.is_validator() -> bool`: Returns True for Validator, Admin, ApiAdmin.
|
||||
|
||||
### Detection
|
||||
| Field | Type |
|
||||
|-------|------|
|
||||
| `annotation_name` | str |
|
||||
| `cls` | int |
|
||||
| `x`, `y`, `w`, `h` | float |
|
||||
| `confidence` | float (optional) |
|
||||
|
||||
### AnnotationCreatedMessageNarrow
|
||||
Lightweight message with only `name` and `createdEmail` (from msgpack fields 1, 2).
|
||||
|
||||
### AnnotationMessage
|
||||
Full annotation message deserialized from msgpack:
|
||||
| Field | Type | Source |
|
||||
|-------|------|--------|
|
||||
| `createdDate` | datetime | msgpack field 0 (Timestamp) |
|
||||
| `name` | str | field 1 |
|
||||
| `originalMediaName` | str | field 2 |
|
||||
| `time` | timedelta | field 3 (microseconds/10) |
|
||||
| `imageExtension` | str | field 4 |
|
||||
| `detections` | list[Detection] | field 5 (JSON string) |
|
||||
| `image` | bytes | field 6 |
|
||||
| `createdRole` | RoleEnum | field 7 |
|
||||
| `createdEmail` | str | field 8 |
|
||||
| `source` | SourceEnum | field 9 |
|
||||
| `status` | AnnotationStatus | field 10 |
|
||||
|
||||
### AnnotationBulkMessage
|
||||
Bulk operation message for validate/delete:
|
||||
| Field | Type | Source |
|
||||
|-------|------|--------|
|
||||
| `annotation_names` | list[str] | msgpack field 0 |
|
||||
| `annotation_status` | AnnotationStatus | field 1 |
|
||||
| `createdEmail` | str | field 2 |
|
||||
| `createdDate` | datetime | field 3 (Timestamp) |
|
||||
|
||||
## Internal Logic
|
||||
- All messages are deserialized from msgpack binary using positional integer keys.
|
||||
- Detections within AnnotationMessage are stored as a JSON string inside the msgpack payload.
|
||||
- Module-level `annotation_classes = AnnotationClass.read_json()` is loaded at import time for Detection.__str__ formatting.
|
||||
|
||||
## Dependencies
|
||||
- `msgpack` (external) — binary message deserialization
|
||||
- `json`, `datetime`, `enum` (stdlib)
|
||||
|
||||
## Consumers
|
||||
annotation-queue/annotation_queue_handler
|
||||
|
||||
## Data Models
|
||||
AnnotationClass, AnnotationStatus, SourceEnum, RoleEnum, Detection, AnnotationCreatedMessageNarrow, AnnotationMessage, AnnotationBulkMessage.
|
||||
|
||||
## Configuration
|
||||
Reads `classes.json` from current working directory.
|
||||
|
||||
## External Integrations
|
||||
None (pure data classes).
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Module: annotation-queue/annotation_queue_handler
|
||||
|
||||
## Purpose
|
||||
Async consumer for the Azaion annotation queue (RabbitMQ Streams). Listens for annotation CRUD events and writes/moves image+label files on the filesystem.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### AnnotationQueueHandler
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `()` | — | Reads config.yaml, creates directories, initializes rstream Consumer, reads offset |
|
||||
| `start` | `async ()` | — | Starts consumer, subscribes to queue stream, runs event loop |
|
||||
| `on_message` | `(message: AMQPMessage, context: MessageContext)` | — | Message callback: routes by AnnotationStatus to save/validate/delete |
|
||||
| `save_annotation` | `(ann: AnnotationMessage)` | — | Writes label file + image to data or seed directory based on role |
|
||||
| `validate` | `(msg: AnnotationBulkMessage)` | — | Moves annotations from seed to data directory |
|
||||
| `delete` | `(msg: AnnotationBulkMessage)` | — | Moves annotations to deleted directory |
|
||||
|
||||
### AnnotationQueueHandler.AnnotationName (inner class)
|
||||
Helper that pre-computes file paths for an annotation name across data/seed directories.
|
||||
|
||||
## Internal Logic
|
||||
- **Queue protocol**: Subscribes to a RabbitMQ Streams queue using rstream library with AMQP message decoding. Resumes from a persisted offset stored in `offset.yaml`.
|
||||
- **Message routing** (via `application_properties['AnnotationStatus']`):
|
||||
- `Created` / `Edited` → `save_annotation`: If validator role, writes to data dir; else writes to seed dir. For Created status, also saves the image bytes. For Edited by validator, moves image from seed to data.
|
||||
- `Validated` → `validate`: Bulk-moves all named annotations from seed to data directory.
|
||||
- `Deleted` → `delete`: Bulk-moves all named annotations to the deleted directory.
|
||||
- **Offset tracking**: After each message, increments offset and persists to `offset.yaml`.
|
||||
- **Directory layout**:
|
||||
- `{root}/data/images/` + `{root}/data/labels/` — validated annotations
|
||||
- `{root}/data-seed/images/` + `{root}/data-seed/labels/` — unvalidated annotations
|
||||
- `{root}/data_deleted/images/` + `{root}/data_deleted/labels/` — soft-deleted annotations
|
||||
- **Logging**: TimedRotatingFileHandler with daily rotation, 7-day retention, logs to `logs/` directory.
|
||||
|
||||
## Dependencies
|
||||
- `annotation_queue_dto` — AnnotationStatus, AnnotationMessage, AnnotationBulkMessage
|
||||
- `rstream` (external) — RabbitMQ Streams consumer
|
||||
- `yaml` (external) — config and offset persistence
|
||||
- `asyncio`, `os`, `shutil`, `sys`, `logging`, `datetime` (stdlib)
|
||||
|
||||
## Consumers
|
||||
None (entry point — runs via `__main__`).
|
||||
|
||||
## Data Models
|
||||
Uses AnnotationMessage, AnnotationBulkMessage from annotation_queue_dto.
|
||||
|
||||
## Configuration
|
||||
- `config.yaml`: API creds (url, email, password), queue config (host, port, consumer_user, consumer_pw, name), directory structure (root, data, data_seed, data_processed, data_deleted, images, labels)
|
||||
- `offset.yaml`: persisted queue consumer offset
|
||||
|
||||
## External Integrations
|
||||
- RabbitMQ Streams queue (rstream library) on host `188.245.120.247:5552`
|
||||
- Filesystem: `/azaion/data/`, `/azaion/data-seed/`, `/azaion/data_deleted/`
|
||||
|
||||
## Security
|
||||
- Queue credentials in `config.yaml` (hardcoded — security concern)
|
||||
- No encryption of annotation data at rest
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Module: api_client
|
||||
|
||||
## Purpose
|
||||
HTTP client for the Azaion backend API. Handles authentication, file upload/download with encryption, and split-resource management (big/small model parts).
|
||||
|
||||
## Public Interface
|
||||
|
||||
### ApiCredentials
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `url` | str | API base URL |
|
||||
| `email` | str | Login email |
|
||||
| `password` | str | Login password |
|
||||
|
||||
### ApiClient
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `()` | — | Reads `config.yaml` for API creds, reads `cdn.yaml` via `load_bytes`, initializes CDNManager |
|
||||
| `login` | `()` | — | POST `/login` → stores JWT token |
|
||||
| `upload_file` | `(filename: str, file_bytes: bytearray, folder: str)` | — | Uploads file to API resource endpoint |
|
||||
| `load_bytes` | `(filename: str, folder: str) -> bytes` | Decrypted bytes | Downloads encrypted resource from API, decrypts with hardware-bound key |
|
||||
| `load_big_small_resource` | `(resource_name: str, folder: str, key: str) -> bytes` | Decrypted bytes | Reassembles a split resource: big part from local disk + small part from API, decrypts combined |
|
||||
| `upload_big_small_resource` | `(resource: bytes, resource_name: str, folder: str, key: str)` | — | Encrypts resource, splits into big (CDN) + small (API), uploads both |
|
||||
|
||||
## Internal Logic
|
||||
- **Authentication**: JWT-based. Auto-login on first request, re-login on 401/403.
|
||||
- **load_bytes**: Sends hardware fingerprint in request payload. Server returns encrypted bytes. Client decrypts using key derived from credentials + hardware hash.
|
||||
- **Split resource pattern**: Large files (models) are split into two parts:
|
||||
- `*.small` — first N bytes (min of `SMALL_SIZE_KB * 1024` or 20% of encrypted size) — stored on API server
|
||||
- `*.big` — remainder — stored on CDN (S3)
|
||||
- This split ensures the model cannot be reconstructed from either storage alone.
|
||||
- **CDN initialization**: On construction, `cdn.yaml` is loaded via `load_bytes` (from API, encrypted), then used to initialize `CDNManager`.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — config file paths, size thresholds, model folder name
|
||||
- `cdn_manager` — CDNCredentials, CDNManager for S3 operations
|
||||
- `hardware_service` — `get_hardware_info()` for hardware fingerprint
|
||||
- `security` — encryption/decryption, key derivation
|
||||
- `requests` (external) — HTTP client
|
||||
- `yaml` (external) — config parsing
|
||||
- `io`, `json`, `os` (stdlib)
|
||||
|
||||
## Consumers
|
||||
exports, train, start_inference
|
||||
|
||||
## Data Models
|
||||
`ApiCredentials` — API connection credentials.
|
||||
|
||||
## Configuration
|
||||
- `config.yaml` — API URL, email, password
|
||||
- `cdn.yaml` — CDN credentials (loaded encrypted from API at init time)
|
||||
|
||||
## External Integrations
|
||||
- Azaion REST API (`POST /login`, `POST /resources/{folder}`, `POST /resources/get/{folder}`)
|
||||
- S3-compatible CDN via CDNManager
|
||||
|
||||
## Security
|
||||
- JWT token-based authentication with auto-refresh on 401/403
|
||||
- Hardware-bound encryption for downloaded resources
|
||||
- Split model storage prevents single-point compromise
|
||||
- Credentials read from `config.yaml` (hardcoded in file — security concern)
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Module: augmentation
|
||||
|
||||
## Purpose
|
||||
Image augmentation pipeline that takes raw annotated images and produces multiple augmented variants for training data expansion. Runs continuously in a loop.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### Augmentator
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `()` | — | Initializes augmentation transforms and counters |
|
||||
| `augment_annotations` | `(from_scratch: bool = False)` | — | Processes all unprocessed images from `data/images` → `data-processed/images` |
|
||||
| `augment_annotation` | `(image_file)` | — | Processes a single image file: reads image + labels, augments, saves results |
|
||||
| `augment_inner` | `(img_ann: ImageLabel) -> list[ImageLabel]` | List of augmented images | Generates 1 original + 7 augmented variants |
|
||||
| `correct_bboxes` | `(labels) -> list` | Corrected labels | Clips bounding boxes to image boundaries, removes tiny boxes |
|
||||
| `read_labels` | `(labels_path) -> list[list]` | Parsed YOLO labels | Reads YOLO-format label file into list of [x, y, w, h, class_id] |
|
||||
|
||||
## Internal Logic
|
||||
- **Augmentation pipeline** (albumentations Compose):
|
||||
1. HorizontalFlip (p=0.6)
|
||||
2. RandomBrightnessContrast (p=0.4)
|
||||
3. Affine: scale 0.8–1.2, rotate ±35°, shear ±10° (p=0.8)
|
||||
4. MotionBlur (p=0.1)
|
||||
5. HueSaturationValue (p=0.4)
|
||||
- Each image produces **8 outputs**: 1 original copy + 7 augmented variants
|
||||
- Naming: `{stem}_{1..7}.jpg` for augmented, original keeps its name
|
||||
- **Bbox correction**: clips bounding boxes that extend outside image borders, removes boxes smaller than `correct_min_bbox_size` (0.01 of image dimension)
|
||||
- **Incremental processing**: skips images already present in `processed_images_dir`
|
||||
- **Concurrent**: uses `ThreadPoolExecutor` for parallel processing
|
||||
- **Continuous mode**: `__main__` runs augmentation in an infinite loop with 5-minute sleep between rounds
|
||||
|
||||
## Dependencies
|
||||
- `constants` — directory paths (data_images_dir, data_labels_dir, processed_*)
|
||||
- `dto/imageLabel` — ImageLabel container class
|
||||
- `albumentations` (external) — augmentation transforms
|
||||
- `cv2` (external) — image read/write
|
||||
- `numpy` (external) — image array handling
|
||||
- `concurrent.futures`, `os`, `shutil`, `time`, `datetime`, `pathlib` (stdlib)
|
||||
|
||||
## Consumers
|
||||
manual_run
|
||||
|
||||
## Data Models
|
||||
Uses `ImageLabel` from `dto/imageLabel`.
|
||||
|
||||
## Configuration
|
||||
Hardcoded augmentation parameters (probabilities, ranges). Directory paths from `constants`.
|
||||
|
||||
## External Integrations
|
||||
Filesystem I/O: reads from `/azaion/data/`, writes to `/azaion/data-processed/`.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,51 @@
|
||||
# Module: cdn_manager
|
||||
|
||||
## Purpose
|
||||
Manages file upload and download to/from an S3-compatible CDN (MinIO/similar) using separate credentials for upload and download operations.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### CDNCredentials
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `host` | str | CDN endpoint URL |
|
||||
| `downloader_access_key` | str | S3 access key for downloads |
|
||||
| `downloader_access_secret` | str | S3 secret for downloads |
|
||||
| `uploader_access_key` | str | S3 access key for uploads |
|
||||
| `uploader_access_secret` | str | S3 secret for uploads |
|
||||
|
||||
### CDNManager
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `(credentials: CDNCredentials)` | — | Creates two boto3 S3 clients (download + upload) |
|
||||
| `upload` | `(bucket: str, filename: str, file_bytes: bytearray) -> bool` | True on success | Uploads bytes to S3 bucket |
|
||||
| `download` | `(bucket: str, filename: str) -> bool` | True on success | Downloads file from S3 to current directory |
|
||||
|
||||
## Internal Logic
|
||||
- Maintains two separate boto3 S3 clients with different credentials (read vs write separation)
|
||||
- Upload uses `upload_fileobj` with in-memory BytesIO wrapper
|
||||
- Download uses `download_file` (saves directly to disk with same filename)
|
||||
- Both methods catch all exceptions, print error, return bool
|
||||
|
||||
## Dependencies
|
||||
- `boto3` (external) — S3 client
|
||||
- `io`, `sys`, `yaml`, `os` (stdlib) — Note: `sys`, `yaml`, `os` are imported but unused
|
||||
|
||||
## Consumers
|
||||
api_client, exports, train, start_inference
|
||||
|
||||
## Data Models
|
||||
`CDNCredentials` — plain data class holding S3 access credentials.
|
||||
|
||||
## Configuration
|
||||
Credentials loaded from `cdn.yaml` by callers (not by this module directly).
|
||||
|
||||
## External Integrations
|
||||
- S3-compatible object storage (configured via `CDNCredentials.host`)
|
||||
|
||||
## Security
|
||||
- Separate read/write credentials enforce least-privilege access
|
||||
- Credentials passed in at construction time, not hardcoded here
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,59 @@
|
||||
# Module: constants
|
||||
|
||||
## Purpose
|
||||
Centralizes all filesystem path constants, config file names, file extensions, and size thresholds used across the training pipeline.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Name | Type | Value/Description |
|
||||
|------|------|-------------------|
|
||||
| `azaion` | str | Root directory: `/azaion` |
|
||||
| `prefix` | str | Naming prefix: `azaion-` |
|
||||
| `data_dir` | str | `/azaion/data` |
|
||||
| `data_images_dir` | str | `/azaion/data/images` |
|
||||
| `data_labels_dir` | str | `/azaion/data/labels` |
|
||||
| `processed_dir` | str | `/azaion/data-processed` |
|
||||
| `processed_images_dir` | str | `/azaion/data-processed/images` |
|
||||
| `processed_labels_dir` | str | `/azaion/data-processed/labels` |
|
||||
| `corrupted_dir` | str | `/azaion/data-corrupted` |
|
||||
| `corrupted_images_dir` | str | `/azaion/data-corrupted/images` |
|
||||
| `corrupted_labels_dir` | str | `/azaion/data-corrupted/labels` |
|
||||
| `sample_dir` | str | `/azaion/data-sample` |
|
||||
| `datasets_dir` | str | `/azaion/datasets` |
|
||||
| `models_dir` | str | `/azaion/models` |
|
||||
| `date_format` | str | `%Y-%m-%d` |
|
||||
| `checkpoint_file` | str | `checkpoint.txt` |
|
||||
| `checkpoint_date_format` | str | `%Y-%m-%d %H:%M:%S` |
|
||||
| `CONFIG_FILE` | str | `config.yaml` |
|
||||
| `JPG_EXT` | str | `.jpg` |
|
||||
| `TXT_EXT` | str | `.txt` |
|
||||
| `OFFSET_FILE` | str | `offset.yaml` |
|
||||
| `SMALL_SIZE_KB` | int | `3` (KB threshold for split-upload small part) |
|
||||
| `CDN_CONFIG` | str | `cdn.yaml` |
|
||||
| `MODELS_FOLDER` | str | `models` |
|
||||
| `CURRENT_PT_MODEL` | str | `/azaion/models/azaion.pt` |
|
||||
| `CURRENT_ONNX_MODEL` | str | `/azaion/models/azaion.onnx` |
|
||||
|
||||
## Internal Logic
|
||||
Pure constant definitions using `os.path.join`. No functions, no classes, no dynamic behavior.
|
||||
|
||||
## Dependencies
|
||||
- `os.path` (stdlib)
|
||||
|
||||
## Consumers
|
||||
api_client, augmentation, exports, train, manual_run, start_inference, dataset-visualiser
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
Defines `CONFIG_FILE = 'config.yaml'` and `CDN_CONFIG = 'cdn.yaml'` — the filenames for runtime configuration. Does not read them.
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Module: convert-annotations
|
||||
|
||||
## Purpose
|
||||
Standalone script that converts annotation files from external formats (Pascal VOC XML, oriented bounding box text) to YOLO format.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Returns | Description |
|
||||
|----------|-----------|---------|-------------|
|
||||
| `convert` | `(folder, dest_folder, read_annotations, ann_format)` | — | Generic converter: reads images + annotations from folder, writes YOLO format to dest |
|
||||
| `minmax2yolo` | `(width, height, xmin, xmax, ymin, ymax) -> tuple` | (cx, cy, w, h) | Converts pixel min/max coords to normalized YOLO center format |
|
||||
| `read_pascal_voc` | `(width, height, s: str) -> list[str]` | YOLO label lines | Parses Pascal VOC XML, maps class names to IDs, outputs YOLO lines |
|
||||
| `read_bbox_oriented` | `(width, height, s: str) -> list[str]` | YOLO label lines | Parses 14-column oriented bbox format, outputs YOLO lines (hardcoded class 2) |
|
||||
| `rename_images` | `(folder)` | — | Renames files by trimming last 7 chars + replacing extension with .png |
|
||||
|
||||
## Internal Logic
|
||||
- **convert()**: Iterates image files in source folder, reads corresponding annotation file, calls format-specific reader, copies image and writes YOLO label to destination.
|
||||
- **Pascal VOC**: Parses XML `<object>` elements, maps class names via `name_class_map` (Truck→1, Car/Taxi→2), filters forbidden classes (Motorcycle). Default class = 1.
|
||||
- **Oriented bbox**: 14-column space-separated format, extracts min/max from columns 6–13, hardcodes class to 2.
|
||||
- **Validation**: Skips labels where normalized coordinates exceed 1.0 (out of bounds).
|
||||
|
||||
## Dependencies
|
||||
- `cv2` (external) — image reading for dimensions
|
||||
- `xml.etree.cElementTree` (stdlib) — Pascal VOC XML parsing
|
||||
- `os`, `shutil`, `pathlib` (stdlib)
|
||||
|
||||
## Consumers
|
||||
None (standalone script).
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
Hardcoded class mappings: `name_class_map = {'Truck': 1, 'Car': 2, 'Taxi': 2}`, `forbidden_classes = ['Motorcycle']`.
|
||||
|
||||
## External Integrations
|
||||
Filesystem I/O only.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Module: dataset-visualiser
|
||||
|
||||
## Purpose
|
||||
Interactive tool for visually inspecting annotated images from datasets or the processed folder, displaying bounding boxes with class colors.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Description |
|
||||
|----------|-----------|-------------|
|
||||
| `visualise_dataset` | `()` | Iterates images in a specific dataset folder, shows each with annotations. Waits for keypress. |
|
||||
| `visualise_processed_folder` | `()` | Shows images from the processed folder with annotations. |
|
||||
|
||||
## Internal Logic
|
||||
- **visualise_dataset()**: Hardcoded to a specific dataset date (`2024-06-18`), iterates from index 35247 onward. Reads image + labels, calls `ImageLabel.visualize()`, waits for user input to advance.
|
||||
- **visualise_processed_folder()**: Lists all processed images, shows the first one.
|
||||
- Both functions use `read_labels()` imported from a `preprocessing` module **which does not exist** in the codebase — this is a broken import.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — directory paths (datasets_dir, prefix, processed_*)
|
||||
- `dto/annotationClass` — AnnotationClass for class colors
|
||||
- `dto/imageLabel` — ImageLabel for visualization
|
||||
- `preprocessing` — **MISSING MODULE** (read_labels function)
|
||||
- `cv2` (external), `matplotlib` (external), `os`, `pathlib` (stdlib)
|
||||
|
||||
## Consumers
|
||||
None (standalone script).
|
||||
|
||||
## Data Models
|
||||
Uses ImageLabel, AnnotationClass.
|
||||
|
||||
## Configuration
|
||||
Hardcoded dataset path and start index.
|
||||
|
||||
## External Integrations
|
||||
Filesystem I/O, matplotlib interactive display.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,49 @@
|
||||
# Module: dto/annotationClass
|
||||
|
||||
## Purpose
|
||||
Defines the `AnnotationClass` data model and `WeatherMode` enum used in the training pipeline. Reads annotation class definitions from `classes.json`.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### WeatherMode (Enum)
|
||||
| Member | Value | Description |
|
||||
|--------|-------|-------------|
|
||||
| `Norm` | 0 | Normal weather |
|
||||
| `Wint` | 20 | Winter conditions |
|
||||
| `Night` | 40 | Night conditions |
|
||||
|
||||
### AnnotationClass
|
||||
| Field/Method | Type/Signature | Description |
|
||||
|-------------|----------------|-------------|
|
||||
| `id` | int | Class ID (weather_offset + base_id) |
|
||||
| `name` | str | Class name (with weather suffix if non-Norm) |
|
||||
| `color` | str | Hex color string (e.g. `#ff0000`) |
|
||||
| `color_tuple` | property → tuple | RGB tuple parsed from hex color |
|
||||
| `read_json()` | static → dict[int, AnnotationClass] | Reads `classes.json`, expands across weather modes, returns dict keyed by ID |
|
||||
|
||||
## Internal Logic
|
||||
- `read_json()` locates `classes.json` relative to the parent directory of the `dto/` package
|
||||
- For each of the 3 weather modes, creates an AnnotationClass per entry in `classes.json` with offset IDs (0, 20, 40)
|
||||
- This produces up to 80 classes total (17 base × 3 modes = 51, but the system reserves 80 slots)
|
||||
- `color_tuple` strips the first 3 characters of the color string and parses hex pairs
|
||||
|
||||
## Dependencies
|
||||
- `json`, `enum`, `os.path` (stdlib)
|
||||
|
||||
## Consumers
|
||||
train (for YAML generation), dataset-visualiser (for visualization colors)
|
||||
|
||||
## Data Models
|
||||
`AnnotationClass` — annotation class with ID, name, color. `WeatherMode` — enum for weather conditions.
|
||||
|
||||
## Configuration
|
||||
Reads `classes.json` from project root (relative path from `dto/` parent).
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None directly; used transitively by `tests/imagelabel_visualize_test.py`.
|
||||
@@ -0,0 +1,41 @@
|
||||
# Module: dto/imageLabel
|
||||
|
||||
## Purpose
|
||||
Container class for an image with its YOLO-format bounding box labels, plus a visualization method for debugging annotations.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### ImageLabel
|
||||
| Field/Method | Type/Signature | Description |
|
||||
|-------------|----------------|-------------|
|
||||
| `image_path` | str | Filesystem path to the image |
|
||||
| `image` | numpy.ndarray | OpenCV image array |
|
||||
| `labels_path` | str | Filesystem path to the labels file |
|
||||
| `labels` | list[list] | List of YOLO bboxes: [x_center, y_center, width, height, class_id] |
|
||||
| `visualize` | `(annotation_classes: dict) -> None` | Draws bounding boxes on image and displays via matplotlib |
|
||||
|
||||
## Internal Logic
|
||||
- `visualize()` converts BGR→RGB, iterates labels, converts normalized YOLO coordinates to pixel coordinates, draws colored rectangles using `annotation_classes[class_num].color_tuple`, displays with matplotlib.
|
||||
- Labels use YOLO format: center_x, center_y, width, height (all normalized 0–1), class_id as last element.
|
||||
|
||||
## Dependencies
|
||||
- `cv2` (external) — image manipulation
|
||||
- `matplotlib.pyplot` (external) — image display
|
||||
|
||||
## Consumers
|
||||
augmentation (as augmented image container), dataset-visualiser (for visualization)
|
||||
|
||||
## Data Models
|
||||
`ImageLabel` — image + labels container.
|
||||
|
||||
## Configuration
|
||||
None.
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
Used by `tests/imagelabel_visualize_test.py`.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Module: exports
|
||||
|
||||
## Purpose
|
||||
Model export utilities: converts trained YOLO .pt models to ONNX, TensorRT, and RKNN formats. Also handles encrypted model upload (split big/small pattern) and data sampling.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Returns | Description |
|
||||
|----------|-----------|---------|-------------|
|
||||
| `export_rknn` | `(model_path: str)` | — | Exports YOLO model to RKNN format (RK3588 target), cleans up temp folder |
|
||||
| `export_onnx` | `(model_path: str, batch_size: int = 4)` | — | Exports YOLO model to ONNX (1280px, NMS enabled, GPU device 0) |
|
||||
| `export_tensorrt` | `(model_path: str)` | — | Exports YOLO model to TensorRT engine (batch=4, half precision, NMS) |
|
||||
| `form_data_sample` | `(destination_path: str, size: int = 500, write_txt_log: bool = False)` | — | Creates a random sample of processed images |
|
||||
| `show_model` | `(model: str = None)` | — | Opens model visualization in netron |
|
||||
| `upload_model` | `(model_path: str, filename: str, size_small_in_kb: int = 3)` | — | Encrypts model, splits big/small, uploads to API + CDN |
|
||||
|
||||
## Internal Logic
|
||||
- **export_onnx**: Removes existing ONNX file if present, exports at 1280px with NMS baked in and simplification.
|
||||
- **export_tensorrt**: Uses YOLO's built-in TensorRT export (batch=4, FP16, NMS, simplify).
|
||||
- **export_rknn**: Exports to RKNN format targeting RK3588 SoC, moves result file and cleans temp directory.
|
||||
- **upload_model**: Encrypts with `Security.get_model_encryption_key()`, splits encrypted bytes at 30%/70% boundary (or `size_small_in_kb * 1024`), uploads small part to API, big part to CDN.
|
||||
- **form_data_sample**: Randomly shuffles processed images, copies first N to destination folder.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — directory paths, model paths, config file names
|
||||
- `api_client` — ApiClient, ApiCredentials for upload
|
||||
- `cdn_manager` — CDNManager, CDNCredentials for CDN upload
|
||||
- `security` — model encryption key, encrypt_to
|
||||
- `utils` — Dotdict for config access
|
||||
- `ultralytics` (external) — YOLO model
|
||||
- `netron` (external) — model visualization
|
||||
- `yaml`, `os`, `shutil`, `random`, `pathlib` (stdlib)
|
||||
|
||||
## Consumers
|
||||
train (export_tensorrt, upload_model, export_onnx)
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
Reads `config.yaml` for API credentials (in `upload_model`), `cdn.yaml` for CDN credentials.
|
||||
|
||||
## External Integrations
|
||||
- Ultralytics YOLO export pipeline
|
||||
- Netron model viewer
|
||||
- Azaion API + CDN for model upload
|
||||
|
||||
## Security
|
||||
- Models are encrypted with AES-256-CBC before upload
|
||||
- Split storage (big on CDN, small on API) prevents single-point compromise
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,38 @@
|
||||
# Module: hardware_service
|
||||
|
||||
## Purpose
|
||||
Collects hardware fingerprint information (CPU, GPU, RAM, drive serial) from the host machine for use in hardware-bound encryption key derivation.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Returns |
|
||||
|----------|-----------|---------|
|
||||
| `get_hardware_info` | `() -> str` | Formatted string: `CPU: {cpu}. GPU: {gpu}. Memory: {memory}. DriveSerial: {drive_serial}` |
|
||||
|
||||
## Internal Logic
|
||||
- Detects OS via `os.name` (`nt` for Windows, else Linux)
|
||||
- **Windows**: PowerShell commands to query `Win32_Processor`, `Win32_VideoController`, `Win32_OperatingSystem`, disk serial
|
||||
- **Linux**: `lscpu`, `lspci`, `free`, `/sys/block/sda/device/` serial
|
||||
- Parses multi-line output: first line = CPU, second = GPU, second-to-last = memory, last = drive serial
|
||||
- Handles multiple GPUs by taking first GPU and last two lines for memory/drive
|
||||
|
||||
## Dependencies
|
||||
- `os`, `subprocess` (stdlib)
|
||||
|
||||
## Consumers
|
||||
api_client (used in `load_bytes` to generate hardware string for encryption)
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
None.
|
||||
|
||||
## External Integrations
|
||||
Executes OS-level shell commands to query hardware.
|
||||
|
||||
## Security
|
||||
The hardware fingerprint is used as input to `Security.get_hw_hash()` and subsequently `Security.get_api_encryption_key()`, binding API encryption to the specific machine.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,55 @@
|
||||
# Module: inference/dto
|
||||
|
||||
## Purpose
|
||||
Data transfer objects for the inference subsystem: Detection, Annotation, and a local copy of AnnotationClass/WeatherMode.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### Detection
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `x` | float | Normalized center X |
|
||||
| `y` | float | Normalized center Y |
|
||||
| `w` | float | Normalized width |
|
||||
| `h` | float | Normalized height |
|
||||
| `cls` | int | Class ID |
|
||||
| `confidence` | float | Detection confidence score |
|
||||
| `overlaps(det2, iou_threshold) -> bool` | method | IoU-based overlap check |
|
||||
|
||||
### Annotation
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| `frame` | numpy.ndarray | Video frame image |
|
||||
| `time` | int/float | Timestamp in the video |
|
||||
| `detections` | list[Detection] | Detected objects in this frame |
|
||||
|
||||
### AnnotationClass (duplicate)
|
||||
Same as `dto/annotationClass.AnnotationClass` but with an additional `opencv_color` field (BGR tuple). Reads from `classes.json` relative to `inference/` parent directory.
|
||||
|
||||
### WeatherMode (duplicate)
|
||||
Same as `dto/annotationClass.WeatherMode`.
|
||||
|
||||
## Internal Logic
|
||||
- `Detection.overlaps()` computes IoU between two bounding boxes and returns True if above threshold.
|
||||
- `AnnotationClass` here adds `opencv_color` as a pre-computed BGR tuple from the hex color for efficient OpenCV rendering.
|
||||
|
||||
## Dependencies
|
||||
- `json`, `enum`, `os.path` (stdlib)
|
||||
|
||||
## Consumers
|
||||
inference/inference
|
||||
|
||||
## Data Models
|
||||
Detection, Annotation, AnnotationClass, WeatherMode.
|
||||
|
||||
## Configuration
|
||||
Reads `classes.json` from project root.
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Module: inference/inference
|
||||
|
||||
## Purpose
|
||||
High-level video inference pipeline. Orchestrates preprocessing → engine inference → postprocessing → visualization for object detection on video streams.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### Inference
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `(engine: InferenceEngine, confidence_threshold, iou_threshold)` | — | Stores engine, thresholds, loads annotation classes |
|
||||
| `preprocess` | `(frames: list) -> np.ndarray` | Batched blob tensor | Normalizes, resizes, and stacks frames into NCHW blob |
|
||||
| `postprocess` | `(batch_frames, batch_timestamps, output) -> list[Annotation]` | Annotations per frame | Extracts detections from raw output, applies confidence filter and NMS |
|
||||
| `process` | `(video: str)` | — | End-to-end: reads video → batched inference → draws + displays results |
|
||||
| `draw` | `(annotation: Annotation)` | — | Draws bounding boxes with class labels on frame, shows via cv2.imshow |
|
||||
| `remove_overlapping_detections` | `(detections: list[Detection]) -> list[Detection]` | Filtered list | Custom NMS: removes overlapping detections keeping higher confidence |
|
||||
|
||||
## Internal Logic
|
||||
- **Video processing**: Reads video via cv2.VideoCapture, processes every 4th frame (frame_count % 4), batches frames to engine batch size.
|
||||
- **Preprocessing**: `cv2.dnn.blobFromImage` with 1/255 scaling, model input size, BGR→RGB swap.
|
||||
- **Postprocessing**: Iterates raw output, filters by confidence threshold, normalizes coordinates from model space to [0,1], creates Detection objects, applies custom NMS.
|
||||
- **Custom NMS**: Pairwise IoU comparison. When two detections overlap above threshold, keeps the one with higher confidence (ties broken by lower class ID).
|
||||
- **Visualization**: Draws colored rectangles and confidence labels using annotation class colors in OpenCV window.
|
||||
|
||||
## Dependencies
|
||||
- `inference/dto` — Detection, Annotation, AnnotationClass
|
||||
- `inference/onnx_engine` — InferenceEngine ABC (type hint)
|
||||
- `cv2` (external) — video I/O, image processing, display
|
||||
- `numpy` (external) — tensor operations
|
||||
|
||||
## Consumers
|
||||
start_inference
|
||||
|
||||
## Data Models
|
||||
Uses Detection, Annotation from `inference/dto`.
|
||||
|
||||
## Configuration
|
||||
`confidence_threshold` and `iou_threshold` set at construction.
|
||||
|
||||
## External Integrations
|
||||
- OpenCV video capture (file or stream input)
|
||||
- OpenCV GUI window for real-time display
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,50 @@
|
||||
# Module: inference/onnx_engine
|
||||
|
||||
## Purpose
|
||||
Defines the abstract `InferenceEngine` base class and the `OnnxEngine` implementation for running ONNX model inference with GPU acceleration.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### InferenceEngine (ABC)
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `__init__` | `(model_path: str, batch_size: int = 1, **kwargs)` | Abstract constructor |
|
||||
| `get_input_shape` | `() -> Tuple[int, int]` | Returns (height, width) of model input |
|
||||
| `get_batch_size` | `() -> int` | Returns the batch size |
|
||||
| `run` | `(input_data: np.ndarray) -> List[np.ndarray]` | Runs inference, returns output tensors |
|
||||
|
||||
### OnnxEngine (extends InferenceEngine)
|
||||
| Method | Signature | Description |
|
||||
|--------|-----------|-------------|
|
||||
| `__init__` | `(model_bytes, batch_size: int = 1, **kwargs)` | Loads ONNX model from bytes, creates InferenceSession with CUDA+CPU providers |
|
||||
| `get_input_shape` | `() -> Tuple[int, int]` | Returns (height, width) from model input shape |
|
||||
| `get_batch_size` | `() -> int` | Returns batch size (from model shape or constructor arg) |
|
||||
| `run` | `(input_data: np.ndarray) -> List[np.ndarray]` | Runs ONNX inference session |
|
||||
|
||||
## Internal Logic
|
||||
- Uses ONNX Runtime with `CUDAExecutionProvider` (primary) and `CPUExecutionProvider` (fallback).
|
||||
- Reads model metadata to extract class names from custom metadata map.
|
||||
- If model input shape has a fixed batch dimension (not -1), overrides the constructor batch_size.
|
||||
|
||||
## Dependencies
|
||||
- `onnxruntime` (external) — ONNX inference runtime
|
||||
- `numpy` (external)
|
||||
- `abc`, `typing` (stdlib)
|
||||
|
||||
## Consumers
|
||||
inference/inference, inference/tensorrt_engine (inherits InferenceEngine), train (imports OnnxEngine)
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
None.
|
||||
|
||||
## External Integrations
|
||||
- ONNX Runtime GPU execution (CUDA)
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,53 @@
|
||||
# Module: inference/tensorrt_engine
|
||||
|
||||
## Purpose
|
||||
TensorRT-based inference engine implementation. Provides GPU-accelerated inference using NVIDIA TensorRT with CUDA memory management, plus ONNX-to-TensorRT conversion.
|
||||
|
||||
## Public Interface
|
||||
|
||||
### TensorRTEngine (extends InferenceEngine)
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `__init__` | `(model_bytes: bytes, **kwargs)` | — | Deserializes TensorRT engine from bytes, allocates CUDA memory |
|
||||
| `get_input_shape` | `() -> Tuple[int, int]` | (height, width) | Returns model input dimensions |
|
||||
| `get_batch_size` | `() -> int` | int | Returns configured batch size |
|
||||
| `run` | `(input_data: np.ndarray) -> List[np.ndarray]` | Output tensors | Runs async inference on CUDA stream |
|
||||
| `get_gpu_memory_bytes` | `(device_id=0) -> int` | GPU memory in bytes | Queries total GPU VRAM via pynvml (static) |
|
||||
| `get_engine_filename` | `(device_id=0) -> str \| None` | Filename string | Generates device-specific engine filename (static) |
|
||||
| `convert_from_onnx` | `(onnx_model: bytes) -> bytes \| None` | Serialized TensorRT plan | Converts ONNX model to TensorRT engine (static) |
|
||||
|
||||
## Internal Logic
|
||||
- **Initialization**: Deserializes TensorRT engine, creates execution context, allocates pinned host memory and device memory for input/output tensors.
|
||||
- **Dynamic shapes**: Handles -1 (dynamic) dimensions, defaults to 1280×1280 for spatial dims, batch size from engine or constructor.
|
||||
- **Output shape**: [batch_size, 300 max detections, 6 values per detection (x1, y1, x2, y2, conf, cls)].
|
||||
- **Inference flow**: Host→Device async copy → execute_async_v3 → synchronize → Device→Host copy.
|
||||
- **ONNX conversion**: Creates TensorRT builder, parses ONNX, configures workspace (90% of GPU memory), enables FP16 if supported, builds serialized network.
|
||||
- **Engine filename**: `azaion.cc_{major}.{minor}_sm_{sm_count}.engine` — uniquely identifies engine per GPU architecture.
|
||||
|
||||
## Dependencies
|
||||
- `inference/onnx_engine` — InferenceEngine ABC
|
||||
- `tensorrt` (external) — TensorRT runtime and builder
|
||||
- `pycuda.driver` (external) — CUDA memory management
|
||||
- `pycuda.autoinit` (external) — CUDA context auto-initialization
|
||||
- `pynvml` (external) — GPU memory query
|
||||
- `numpy`, `json`, `struct`, `re`, `subprocess`, `pathlib`, `typing` (stdlib/external)
|
||||
|
||||
## Consumers
|
||||
start_inference
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
None.
|
||||
|
||||
## External Integrations
|
||||
- NVIDIA TensorRT runtime (GPU inference)
|
||||
- CUDA driver API (memory allocation, streams)
|
||||
- NVML (GPU hardware queries)
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Module: manual_run
|
||||
|
||||
## Purpose
|
||||
Ad-hoc script for manual training operations. Contains commented-out alternatives and a hardcoded workflow for copying model weights and exporting.
|
||||
|
||||
## Public Interface
|
||||
No functions or classes. Script-level code only.
|
||||
|
||||
## Internal Logic
|
||||
- Contains commented-out calls to `Augmentator().augment_annotations()`, `train.train_dataset()`, `train.resume_training()`.
|
||||
- Active code: references a specific model date (`2025-05-18`), removes intermediate epoch checkpoint files, copies `best.pt` to `CURRENT_PT_MODEL`, then calls `train.export_current_model()`.
|
||||
- Serves as a developer convenience script for one-off training/export operations.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — models_dir, prefix, CURRENT_PT_MODEL
|
||||
- `train` — export_current_model
|
||||
- `augmentation` — Augmentator (imported, usage commented out)
|
||||
- `glob`, `os`, `shutil` (stdlib)
|
||||
|
||||
## Consumers
|
||||
None (standalone script).
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
Hardcoded model date: `2025-05-18`.
|
||||
|
||||
## External Integrations
|
||||
Filesystem operations on `/azaion/models/`.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Module: security
|
||||
|
||||
## Purpose
|
||||
Provides AES-256-CBC encryption/decryption and key derivation functions used to protect model files and API resources in transit.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Method | Signature | Returns | Description |
|
||||
|--------|-----------|---------|-------------|
|
||||
| `Security.encrypt_to` | `(input_bytes: bytes, key: str) -> bytes` | IV + ciphertext | AES-256-CBC encrypt with PKCS7 padding; prepends 16-byte random IV |
|
||||
| `Security.decrypt_to` | `(ciphertext_with_iv_bytes: bytes, key: str) -> bytes` | plaintext bytes | Extracts IV from first 16 bytes, decrypts, removes PKCS7 padding |
|
||||
| `Security.calc_hash` | `(key: str) -> str` | base64-encoded SHA-384 hash | General-purpose hash function |
|
||||
| `Security.get_hw_hash` | `(hardware: str) -> str` | base64 hash | Derives a hardware-specific hash using `Azaion_{hardware}_%$$$)0_` salt |
|
||||
| `Security.get_api_encryption_key` | `(creds, hardware_hash: str) -> str` | base64 hash | Derives API encryption key from credentials + hardware hash |
|
||||
| `Security.get_model_encryption_key` | `() -> str` | base64 hash | Returns a fixed encryption key derived from a hardcoded secret string |
|
||||
|
||||
## Internal Logic
|
||||
- Encryption: SHA-256 of the key string → 32-byte AES key. Random 16-byte IV generated per encryption. PKCS7 padding applied. Output = IV ∥ ciphertext.
|
||||
- Decryption: First 16 bytes = IV, remainder = ciphertext. Manual PKCS7 unpadding (checks last byte is 1–16).
|
||||
- Key derivation uses SHA-384 + base64 encoding for all hash-based keys.
|
||||
- `BUFFER_SIZE = 64 * 1024` is declared but unused.
|
||||
|
||||
## Dependencies
|
||||
- `cryptography.hazmat` (external) — AES cipher, CBC mode, PKCS7 padding
|
||||
- `hashlib`, `base64`, `os` (stdlib)
|
||||
|
||||
## Consumers
|
||||
api_client, exports, train, start_inference, tests/security_test
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
None consumed at runtime. Contains hardcoded key material.
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
- **Hardcoded model encryption key**: `get_model_encryption_key()` uses a static string `'-#%@AzaionKey@%#---234sdfklgvhjbnn'`. This is a significant security concern — the key should be stored in a secrets manager or environment variable.
|
||||
- API encryption key is derived from user credentials + hardware fingerprint, providing per-device uniqueness.
|
||||
- AES-256-CBC with random IV is cryptographically sound for symmetric encryption.
|
||||
|
||||
## Tests
|
||||
- `tests/security_test.py` — basic round-trip encrypt/decrypt test (script-based, no test framework).
|
||||
@@ -0,0 +1,52 @@
|
||||
# Module: start_inference
|
||||
|
||||
## Purpose
|
||||
Entry point for running inference on video files using a TensorRT engine. Downloads the encrypted model from the API/CDN, initializes the engine, and processes video.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Returns | Description |
|
||||
|----------|-----------|---------|-------------|
|
||||
| `get_engine_filename` | `(device_id=0) -> str \| None` | Engine filename | Generates GPU-specific engine filename (duplicate of TensorRTEngine.get_engine_filename) |
|
||||
|
||||
`__main__` block: Creates ApiClient, downloads encrypted TensorRT model (split big/small), initializes TensorRTEngine, runs Inference on a test video.
|
||||
|
||||
## Internal Logic
|
||||
- **Model download flow**: ApiClient → `load_big_small_resource` → reassembles from local big part + API-downloaded small part → decrypts with model encryption key → raw engine bytes.
|
||||
- **Inference setup**: TensorRTEngine initialized from decrypted bytes, Inference configured with confidence_threshold=0.5, iou_threshold=0.3.
|
||||
- **Video source**: Hardcoded to `tests/ForAI_test.mp4`.
|
||||
- **get_engine_filename()**: Duplicates `TensorRTEngine.get_engine_filename()` — generates `azaion.cc_{major}.{minor}_sm_{sm_count}.engine` based on CUDA device compute capability and SM count.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — config file paths
|
||||
- `api_client` — ApiClient, ApiCredentials for model download
|
||||
- `cdn_manager` — CDNManager, CDNCredentials (imported but CDN managed by api_client)
|
||||
- `inference/inference` — Inference pipeline
|
||||
- `inference/tensorrt_engine` — TensorRTEngine
|
||||
- `security` — model encryption key
|
||||
- `utils` — Dotdict
|
||||
- `pycuda.driver` (external) — CUDA device queries
|
||||
- `yaml` (external)
|
||||
|
||||
## Consumers
|
||||
None (entry point).
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
- Confidence threshold: 0.5
|
||||
- IoU threshold: 0.3
|
||||
- Video path: `tests/ForAI_test.mp4` (hardcoded)
|
||||
|
||||
## External Integrations
|
||||
- Azaion API + CDN for model download
|
||||
- TensorRT GPU inference
|
||||
- OpenCV video capture and display
|
||||
|
||||
## Security
|
||||
- Model is downloaded encrypted (split big/small) and decrypted locally
|
||||
- Uses hardware-bound and model encryption keys
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,61 @@
|
||||
# Module: train
|
||||
|
||||
## Purpose
|
||||
Main training pipeline. Forms YOLO datasets from processed annotations, trains YOLOv11 models, and exports/uploads the trained model.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Function | Signature | Returns | Description |
|
||||
|----------|-----------|---------|-------------|
|
||||
| `form_dataset` | `()` | — | Creates train/valid/test split from processed images |
|
||||
| `copy_annotations` | `(images, folder: str)` | — | Copies image+label pairs to a dataset split folder (concurrent) |
|
||||
| `check_label` | `(label_path: str) -> bool` | bool | Validates YOLO label file (all coords ≤ 1.0) |
|
||||
| `create_yaml` | `()` | — | Generates YOLO `data.yaml` with class names from `classes.json` |
|
||||
| `resume_training` | `(last_pt_path: str)` | — | Resumes training from a checkpoint |
|
||||
| `train_dataset` | `()` | — | Full pipeline: form_dataset → create_yaml → train YOLOv11 → save model |
|
||||
| `export_current_model` | `()` | — | Exports current .pt to ONNX, encrypts, uploads as split resource |
|
||||
|
||||
## Internal Logic
|
||||
- **Dataset formation**: Shuffles all processed images, splits 70/20/10 (train/valid/test). Copies in parallel via ThreadPoolExecutor. Corrupted labels (coords > 1.0) are moved to `/azaion/data-corrupted/`.
|
||||
- **YAML generation**: Reads annotation classes from `classes.json`, builds `data.yaml` with 80 class names (17 actual + 63 placeholders "Class-N"), sets train/valid/test paths.
|
||||
- **Training**: YOLOv11 medium (`yolo11m.yaml`), 120 epochs, batch=11 (tuned for 24GB VRAM), 1280px input, save every epoch, 24 workers.
|
||||
- **Post-training**: Copies results to `/azaion/models/{date}/`, removes intermediate epoch checkpoints, copies `best.pt` to `CURRENT_PT_MODEL`.
|
||||
- **Export**: Calls `export_onnx`, reads the ONNX file, encrypts with model key, uploads via `upload_big_small_resource`.
|
||||
- **Dataset naming**: `azaion-{YYYY-MM-DD}` using current date.
|
||||
- **`__main__`**: Runs `train_dataset()` then `export_current_model()`.
|
||||
|
||||
## Dependencies
|
||||
- `constants` — all directory/path constants
|
||||
- `api_client` — ApiClient for model upload
|
||||
- `cdn_manager` — CDNCredentials, CDNManager (imported but CDN init done via api_client)
|
||||
- `dto/annotationClass` — AnnotationClass for class name generation
|
||||
- `inference/onnx_engine` — OnnxEngine (imported but unused in current code)
|
||||
- `security` — model encryption key
|
||||
- `utils` — Dotdict
|
||||
- `exports` — export_tensorrt, upload_model, export_onnx
|
||||
- `ultralytics` (external) — YOLO training and export
|
||||
- `yaml`, `concurrent.futures`, `glob`, `os`, `random`, `shutil`, `subprocess`, `datetime`, `pathlib`, `time` (stdlib)
|
||||
|
||||
## Consumers
|
||||
manual_run
|
||||
|
||||
## Data Models
|
||||
Uses AnnotationClass for class definitions.
|
||||
|
||||
## Configuration
|
||||
- Training hyperparameters hardcoded: epochs=120, batch=11, imgsz=1280, save_period=1, workers=24
|
||||
- Dataset split ratios: train_set=70, valid_set=20, test_set=10
|
||||
- old_images_percentage=75 (declared but unused)
|
||||
- DEFAULT_CLASS_NUM=80
|
||||
|
||||
## External Integrations
|
||||
- Ultralytics YOLOv11 training pipeline
|
||||
- Azaion API + CDN for model upload
|
||||
- Filesystem: `/azaion/datasets/`, `/azaion/models/`, `/azaion/data-processed/`, `/azaion/data-corrupted/`
|
||||
|
||||
## Security
|
||||
- Trained models are encrypted before upload
|
||||
- Uses `Security.get_model_encryption_key()` for encryption
|
||||
|
||||
## Tests
|
||||
None.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Module: utils
|
||||
|
||||
## Purpose
|
||||
Provides a dictionary subclass that supports dot-notation attribute access.
|
||||
|
||||
## Public Interface
|
||||
|
||||
| Name | Type | Signature |
|
||||
|------|------|-----------|
|
||||
| `Dotdict` | class (extends `dict`) | `Dotdict(dict)` |
|
||||
|
||||
`Dotdict` overrides `__getattr__`, `__setattr__`, `__delattr__` to delegate to `dict.get`, `dict.__setitem__`, `dict.__delitem__` respectively.
|
||||
|
||||
## Internal Logic
|
||||
Single-class module. Allows `config.url` instead of `config["url"]` for YAML-loaded dicts.
|
||||
|
||||
## Dependencies
|
||||
None (stdlib `dict` only).
|
||||
|
||||
## Consumers
|
||||
exports, train, start_inference
|
||||
|
||||
## Data Models
|
||||
None.
|
||||
|
||||
## Configuration
|
||||
None.
|
||||
|
||||
## External Integrations
|
||||
None.
|
||||
|
||||
## Security
|
||||
None.
|
||||
|
||||
## Tests
|
||||
None.
|
||||
Reference in New Issue
Block a user