javasop commited on
Commit
42f02f2
·
verified ·
1 Parent(s): dadbb83

Upload folder using huggingface_hub

Browse files
Dockerfile CHANGED
@@ -1,4 +1,10 @@
1
- FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-devel
 
 
 
 
 
 
2
 
3
  WORKDIR /app
4
 
@@ -6,18 +12,25 @@ WORKDIR /app
6
  RUN apt-get update && apt-get install -y \
7
  git \
8
  curl \
 
 
9
  && rm -rf /var/lib/apt/lists/*
10
 
 
 
 
 
 
11
  # Copy requirements and install Python dependencies
12
  COPY requirements.txt .
13
- RUN pip install --no-cache-dir -r requirements.txt
 
14
 
15
  # Copy training code
16
  COPY . .
17
 
18
- # Set environment variables
19
- ENV PYTHONUNBUFFERED=1
20
- ENV HF_HOME=/app/.cache/huggingface
21
 
22
- # Default command
23
- CMD ["python", "train.py", "--config", "config.yaml"]
 
1
+ FROM pytorch/pytorch:2.2.0-cuda12.1-cudnn8-devel
2
+
3
+ # Set environment variables
4
+ ENV PYTHONUNBUFFERED=1
5
+ ENV HF_HOME=/app/.cache/huggingface
6
+ ENV TRANSFORMERS_CACHE=/app/.cache/huggingface/transformers
7
+ ENV DEBIAN_FRONTEND=noninteractive
8
 
9
  WORKDIR /app
10
 
 
12
  RUN apt-get update && apt-get install -y \
13
  git \
14
  curl \
15
+ wget \
16
+ build-essential \
17
  && rm -rf /var/lib/apt/lists/*
18
 
19
+ # Download orbital CLI from HuggingFace (has native validation, no kflow needed)
20
+ RUN wget -q https://huggingface.co/orbital-ai/orbital-cli/resolve/main/orbital-linux-x86_64 -O /usr/local/bin/orbital \
21
+ && chmod +x /usr/local/bin/orbital \
22
+ && orbital --version || echo "Orbital CLI installed"
23
+
24
  # Copy requirements and install Python dependencies
25
  COPY requirements.txt .
26
+ RUN pip install --no-cache-dir --upgrade pip && \
27
+ pip install --no-cache-dir -r requirements.txt
28
 
29
  # Copy training code
30
  COPY . .
31
 
32
+ # Create cache directories
33
+ RUN mkdir -p /app/.cache/huggingface
 
34
 
35
+ # Default command - uses HuggingFace config
36
+ CMD ["python", "train.py", "--config", "config-huggingface.yaml"]
README.md CHANGED
@@ -1,37 +1,47 @@
 
 
 
 
 
 
 
 
 
 
1
  # OrbGen Training
2
 
3
  Training code for OrbGen - a model that generates valid Orbital schemas from natural language.
4
 
5
  ## Quick Start
6
 
7
- ### 1. Install Dependencies
8
 
9
  ```bash
 
10
  pip install -r requirements.txt
11
- ```
12
-
13
- ### 2. Configure Training
14
-
15
- Edit `config.yaml` to adjust:
16
- - Base model
17
- - Training hyperparameters
18
- - LoRA configuration
19
- - W&B settings
20
-
21
- ### 3. Train
22
 
23
- ```bash
24
- # Full training
25
  python train.py --config config.yaml
26
 
27
  # Debug mode (1 epoch, no W&B)
28
  python train.py --config config.yaml --debug
 
29
 
30
- # Resume from checkpoint
31
- python train.py --config config.yaml --resume_from_checkpoint ./orbgen-1.5b/checkpoint-500
 
 
 
32
  ```
33
 
34
- ### 4. Evaluate
 
 
 
 
 
 
 
35
 
36
  ```bash
37
  # Basic evaluation
@@ -41,7 +51,7 @@ python evaluate.py --checkpoint ./orbgen-1.5b/final
41
  python evaluate.py --checkpoint ./orbgen-1.5b/final --use_validator
42
  ```
43
 
44
- ### 5. Generate
45
 
46
  ```bash
47
  # Single generation
@@ -61,28 +71,41 @@ python generate.py --prompt "..." --output schema.orb --validate
61
  | `train.py` | Main training script with SFT |
62
  | `evaluate.py` | Evaluation with Orbital validation |
63
  | `generate.py` | Inference and generation |
64
- | `config.yaml` | Training configuration |
65
- | `Dockerfile` | Container for training |
 
66
  | `requirements.txt` | Python dependencies |
67
 
68
  ## Training on HuggingFace Spaces
69
 
70
- 1. Push this directory to `orbital-ai/orbgen-training`:
 
 
71
  ```bash
72
- hf upload orbital-ai/orbgen-training . --repo-type space
73
  ```
74
 
75
- 2. Configure the Space with A10G GPU
 
 
76
 
77
- 3. Training will start automatically
 
 
 
 
 
 
 
 
78
 
79
  ## Hardware Requirements
80
 
81
- | Phase | GPU | VRAM | Time |
82
- |-------|-----|------|------|
83
- | Training (3 epochs) | A10G | 24GB | ~6 hours |
84
- | Evaluation | T4 | 16GB | ~30 min |
85
- | Inference | T4 | 16GB | ~1 sec/gen |
86
 
87
  ## Model Output
88
 
@@ -92,7 +115,4 @@ After training, the model is saved to `./orbgen-1.5b/final/`:
92
  - `tokenizer.json` - Tokenizer
93
  - `config.json` - Model config
94
 
95
- To push to HuggingFace:
96
- ```bash
97
- hf upload orbital-ai/orbgen-1.5b ./orbgen-1.5b/final --repo-type model
98
- ```
 
1
+ ---
2
+ title: OrbGen Training
3
+ emoji: 🚀
4
+ colorFrom: blue
5
+ colorTo: purple
6
+ sdk: docker
7
+ pinned: false
8
+ license: apache-2.0
9
+ ---
10
+
11
  # OrbGen Training
12
 
13
  Training code for OrbGen - a model that generates valid Orbital schemas from natural language.
14
 
15
  ## Quick Start
16
 
17
+ ### Local Training
18
 
19
  ```bash
20
+ # Install dependencies
21
  pip install -r requirements.txt
 
 
 
 
 
 
 
 
 
 
 
22
 
23
+ # Full training (with local GPU)
 
24
  python train.py --config config.yaml
25
 
26
  # Debug mode (1 epoch, no W&B)
27
  python train.py --config config.yaml --debug
28
+ ```
29
 
30
+ ### HuggingFace Cloud Training
31
+
32
+ ```bash
33
+ # Use the HuggingFace-optimized config
34
+ python train.py --config config-huggingface.yaml
35
  ```
36
 
37
+ ## Configuration Files
38
+
39
+ | Config | GPU | VRAM | Use Case |
40
+ |--------|-----|------|----------|
41
+ | `config.yaml` | Local (RTX 3000) | 6GB | Local testing with QLoRA |
42
+ | `config-huggingface.yaml` | A10G | 24GB | HuggingFace Spaces training |
43
+
44
+ ## Evaluation
45
 
46
  ```bash
47
  # Basic evaluation
 
51
  python evaluate.py --checkpoint ./orbgen-1.5b/final --use_validator
52
  ```
53
 
54
+ ## Generate
55
 
56
  ```bash
57
  # Single generation
 
71
  | `train.py` | Main training script with SFT |
72
  | `evaluate.py` | Evaluation with Orbital validation |
73
  | `generate.py` | Inference and generation |
74
+ | `config.yaml` | Config for local 6GB GPU (QLoRA) |
75
+ | `config-huggingface.yaml` | Config for HuggingFace A10G (24GB) |
76
+ | `Dockerfile` | Container for HuggingFace Spaces |
77
  | `requirements.txt` | Python dependencies |
78
 
79
  ## Training on HuggingFace Spaces
80
 
81
+ ### Prerequisites
82
+
83
+ 1. Upload dataset to HuggingFace:
84
  ```bash
85
+ python scripts/upload_dataset.py
86
  ```
87
 
88
+ 2. Set Space secrets:
89
+ - `HUGGINGFACE_TOKEN` - HF token with write access
90
+ - `WANDB_API_KEY` - Weights & Biases API key
91
 
92
+ 3. Push training code:
93
+ ```bash
94
+ cd orbgen-training
95
+ huggingface-cli upload orbital-ai/orbgen-training . --repo-type space
96
+ ```
97
+
98
+ 4. Configure Space with A10G GPU in settings
99
+
100
+ 5. Training will start automatically
101
 
102
  ## Hardware Requirements
103
 
104
+ | Phase | GPU | VRAM | Notes |
105
+ |-------|-----|------|-------|
106
+ | Training (local) | RTX 3000 | 6GB | Uses QLoRA (4-bit) |
107
+ | Training (cloud) | A10G | 24GB | Full bf16 training |
108
+ | Inference | T4 | 16GB | Production inference |
109
 
110
  ## Model Output
111
 
 
115
  - `tokenizer.json` - Tokenizer
116
  - `config.json` - Model config
117
 
118
+ Model is automatically pushed to `orbital-ai/orbgen-1.5b` when using HuggingFace config.
 
 
 
config-huggingface.yaml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # OrbGen Training Configuration
2
+ # Optimized for HuggingFace Spaces with A10G GPU (24GB VRAM)
3
+
4
+ model:
5
+ base_model: "Qwen/Qwen2.5-Coder-1.5B"
6
+ output_dir: "./orbgen-1.5b"
7
+ max_seq_length: 4096 # Full context for schema generation
8
+
9
+ data:
10
+ # Load from HuggingFace Hub (upload dataset first)
11
+ dataset: "orbital-ai/orbital-schemas"
12
+ train_split: "train"
13
+ eval_split: "validation"
14
+
15
+ training:
16
+ # SFT Configuration - optimized for A10G (24GB VRAM)
17
+ num_epochs: 3
18
+ per_device_train_batch_size: 4 # Can use larger batches
19
+ per_device_eval_batch_size: 4
20
+ gradient_accumulation_steps: 4 # Effective batch size = 16
21
+ learning_rate: 2.0e-5
22
+ warmup_ratio: 0.1
23
+ weight_decay: 0.01
24
+ max_grad_norm: 1.0
25
+
26
+ # Logging
27
+ logging_steps: 10
28
+ eval_steps: 50
29
+ save_steps: 100
30
+ save_total_limit: 3
31
+
32
+ lora:
33
+ enabled: true
34
+ r: 64 # Full LoRA rank
35
+ lora_alpha: 128
36
+ lora_dropout: 0.05
37
+ target_modules:
38
+ - "q_proj"
39
+ - "k_proj"
40
+ - "v_proj"
41
+ - "o_proj"
42
+ - "gate_proj"
43
+ - "up_proj"
44
+ - "down_proj"
45
+ bias: "none"
46
+ task_type: "CAUSAL_LM"
47
+
48
+ # No quantization needed - enough VRAM for bf16
49
+ quantization:
50
+ enabled: false
51
+
52
+ generation:
53
+ max_new_tokens: 4096
54
+ temperature: 0.7
55
+ top_p: 0.95
56
+ do_sample: true
57
+
58
+ wandb:
59
+ project: "orbgen-training"
60
+ entity: null # Will use default
61
+ run_name: "orbgen-1.5b-sft-hf"
62
+
63
+ # HuggingFace Hub settings
64
+ hub:
65
+ push_to_hub: true
66
+ hub_model_id: "orbital-ai/orbgen-1.5b"
67
+ hub_strategy: "checkpoint"
config.yaml CHANGED
@@ -1,21 +1,22 @@
1
  # OrbGen Training Configuration
 
2
 
3
  model:
4
  base_model: "Qwen/Qwen2.5-Coder-1.5B"
5
  output_dir: "./orbgen-1.5b"
6
- max_seq_length: 8192
7
 
8
  data:
9
- dataset: "orbital-ai/orbital-schemas"
10
- train_split: "train"
11
- eval_split: "validation"
12
 
13
  training:
14
- # SFT Configuration
15
  num_epochs: 3
16
- per_device_train_batch_size: 2
17
- per_device_eval_batch_size: 2
18
- gradient_accumulation_steps: 8
19
  learning_rate: 2.0e-5
20
  warmup_ratio: 0.1
21
  weight_decay: 0.01
@@ -25,12 +26,12 @@ training:
25
  logging_steps: 10
26
  eval_steps: 50
27
  save_steps: 100
28
- save_total_limit: 3
29
 
30
  lora:
31
  enabled: true
32
- r: 64
33
- lora_alpha: 128
34
  lora_dropout: 0.05
35
  target_modules:
36
  - "q_proj"
@@ -43,8 +44,16 @@ lora:
43
  bias: "none"
44
  task_type: "CAUSAL_LM"
45
 
 
 
 
 
 
 
 
 
46
  generation:
47
- max_new_tokens: 4096
48
  temperature: 0.7
49
  top_p: 0.95
50
  do_sample: true
@@ -52,4 +61,4 @@ generation:
52
  wandb:
53
  project: "orbgen-training"
54
  entity: "orbital-ai"
55
- run_name: "orbgen-1.5b-sft"
 
1
  # OrbGen Training Configuration
2
+ # Optimized for 6GB VRAM (Quadro RTX 3000)
3
 
4
  model:
5
  base_model: "Qwen/Qwen2.5-Coder-1.5B"
6
  output_dir: "./orbgen-1.5b"
7
+ max_seq_length: 2048 # Reduced from 8192 for low VRAM
8
 
9
  data:
10
+ # Use local files instead of HuggingFace (schema mismatch issue)
11
+ train_file: "../training-data/combined-train.jsonl"
12
+ eval_file: "../training-data/combined-validation.jsonl"
13
 
14
  training:
15
+ # SFT Configuration - optimized for 6GB VRAM
16
  num_epochs: 3
17
+ per_device_train_batch_size: 1 # Reduced from 2
18
+ per_device_eval_batch_size: 1 # Reduced from 2
19
+ gradient_accumulation_steps: 16 # Increased to compensate for smaller batch
20
  learning_rate: 2.0e-5
21
  warmup_ratio: 0.1
22
  weight_decay: 0.01
 
26
  logging_steps: 10
27
  eval_steps: 50
28
  save_steps: 100
29
+ save_total_limit: 2 # Reduced to save disk space
30
 
31
  lora:
32
  enabled: true
33
+ r: 32 # Reduced from 64 to save memory
34
+ lora_alpha: 64 # Reduced proportionally
35
  lora_dropout: 0.05
36
  target_modules:
37
  - "q_proj"
 
44
  bias: "none"
45
  task_type: "CAUSAL_LM"
46
 
47
+ # 4-bit quantization for low VRAM
48
+ quantization:
49
+ enabled: true
50
+ load_in_4bit: true
51
+ bnb_4bit_compute_dtype: "bfloat16"
52
+ bnb_4bit_quant_type: "nf4"
53
+ bnb_4bit_use_double_quant: true
54
+
55
  generation:
56
+ max_new_tokens: 2048 # Reduced from 4096
57
  temperature: 0.7
58
  top_p: 0.95
59
  do_sample: true
 
61
  wandb:
62
  project: "orbgen-training"
63
  entity: "orbital-ai"
64
+ run_name: "orbgen-1.5b-sft-qlora"
evaluate.py CHANGED
@@ -36,12 +36,18 @@ def validate_schema(schema_json: str) -> tuple[bool, list[str]]:
36
  temp_path = f.name
37
 
38
  try:
 
 
 
 
 
 
 
39
  result = subprocess.run(
40
- ['orbital', 'validate', temp_path],
41
  capture_output=True,
42
  text=True,
43
  timeout=30,
44
- cwd=os.path.expanduser('~/kflow.ai.builder/builder')
45
  )
46
 
47
  if result.returncode == 0 or 'Schema is valid' in result.stdout:
@@ -52,7 +58,7 @@ def validate_schema(schema_json: str) -> tuple[bool, list[str]]:
52
  except subprocess.TimeoutExpired:
53
  return False, ["Validation timeout"]
54
  except FileNotFoundError:
55
- return False, ["Orbital CLI not found"]
56
  except Exception as e:
57
  return False, [f"Validation error: {e}"]
58
  finally:
 
36
  temp_path = f.name
37
 
38
  try:
39
+ # Find orbital binary - check multiple locations
40
+ orbital_cmd = 'orbital'
41
+ for path in ['/usr/local/bin/orbital', os.path.expanduser('~/kflow.ai.builder/orbital-rust/target/release/orbital')]:
42
+ if os.path.exists(path):
43
+ orbital_cmd = path
44
+ break
45
+
46
  result = subprocess.run(
47
+ [orbital_cmd, 'validate', temp_path],
48
  capture_output=True,
49
  text=True,
50
  timeout=30,
 
51
  )
52
 
53
  if result.returncode == 0 or 'Schema is valid' in result.stdout:
 
58
  except subprocess.TimeoutExpired:
59
  return False, ["Validation timeout"]
60
  except FileNotFoundError:
61
+ return False, ["Orbital CLI not found - install it or use --use_validator=False"]
62
  except Exception as e:
63
  return False, [f"Validation error: {e}"]
64
  finally:
requirements.txt CHANGED
@@ -1,15 +1,15 @@
1
  # OrbGen Training Dependencies
2
  torch>=2.1.0
3
- transformers>=4.36.0
4
- datasets>=2.16.0
5
- peft>=0.7.0
6
- trl>=0.7.0
7
- accelerate>=0.25.0
8
- bitsandbytes>=0.41.0
9
  wandb>=0.16.0
10
- huggingface_hub>=0.20.0
11
  safetensors>=0.4.0
12
- sentencepiece>=0.1.99
13
  protobuf>=4.25.0
14
  pyyaml>=6.0
15
  fire>=0.5.0
 
1
  # OrbGen Training Dependencies
2
  torch>=2.1.0
3
+ transformers>=4.40.0
4
+ datasets>=2.18.0
5
+ peft>=0.10.0
6
+ trl>=0.8.0
7
+ accelerate>=0.28.0
8
+ bitsandbytes>=0.43.0
9
  wandb>=0.16.0
10
+ huggingface_hub>=0.22.0
11
  safetensors>=0.4.0
12
+ sentencepiece>=0.2.0
13
  protobuf>=4.25.0
14
  pyyaml>=6.0
15
  fire>=0.5.0
scripts/bundle_kflow.sh ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+ # Bundle kflow CLI into a single file for distribution
3
+ # Run from builder/ directory
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+ BUILDER_DIR="$SCRIPT_DIR/../../../../builder"
9
+ OUTPUT_DIR="$SCRIPT_DIR/../bin"
10
+
11
+ echo "Bundling kflow CLI..."
12
+ echo "Builder dir: $BUILDER_DIR"
13
+
14
+ cd "$BUILDER_DIR"
15
+
16
+ # Ensure dependencies are installed
17
+ npm install --workspace=@kflow-builder/compiler --workspace=@kflow-builder/shared
18
+
19
+ # Build shared first
20
+ npm run build:shared
21
+
22
+ # Bundle kflow CLI with esbuild
23
+ mkdir -p "$OUTPUT_DIR"
24
+
25
+ npx esbuild packages/compiler/src/cli/index.ts \
26
+ --bundle \
27
+ --platform=node \
28
+ --target=node18 \
29
+ --outfile="$OUTPUT_DIR/kflow-bundle.js" \
30
+ --external:esbuild \
31
+ --external:typescript \
32
+ --external:@swc/core \
33
+ --format=esm \
34
+ --sourcemap
35
+
36
+ # Create wrapper script
37
+ cat > "$OUTPUT_DIR/kflow" << 'EOF'
38
+ #!/usr/bin/env node
39
+ import('./kflow-bundle.js');
40
+ EOF
41
+
42
+ chmod +x "$OUTPUT_DIR/kflow"
43
+
44
+ echo "Bundle created at: $OUTPUT_DIR/kflow-bundle.js"
45
+ echo "Wrapper at: $OUTPUT_DIR/kflow"
46
+
47
+ # Get size
48
+ ls -lh "$OUTPUT_DIR/kflow-bundle.js"
scripts/upload_dataset.py ADDED
@@ -0,0 +1,185 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Upload OrbGen training dataset to HuggingFace Hub.
4
+
5
+ Usage:
6
+ python scripts/upload_dataset.py
7
+ python scripts/upload_dataset.py --repo orbital-ai/orbital-schemas
8
+ """
9
+
10
+ import os
11
+ import json
12
+ import argparse
13
+ from pathlib import Path
14
+ from huggingface_hub import HfApi, create_repo, upload_file
15
+ from datasets import Dataset, DatasetDict
16
+
17
+
18
+ def load_jsonl(path: str) -> list:
19
+ """Load JSONL file into list of dicts."""
20
+ data = []
21
+ with open(path, 'r') as f:
22
+ for line in f:
23
+ if line.strip():
24
+ data.append(json.loads(line))
25
+ return data
26
+
27
+
28
+ def main():
29
+ parser = argparse.ArgumentParser(description='Upload dataset to HuggingFace')
30
+ parser.add_argument('--repo', default='orbital-ai/orbital-schemas',
31
+ help='HuggingFace dataset repository')
32
+ parser.add_argument('--data-dir', default='../../training-data',
33
+ help='Directory containing JSONL files')
34
+ parser.add_argument('--private', action='store_true',
35
+ help='Make dataset private')
36
+ args = parser.parse_args()
37
+
38
+ # Resolve paths
39
+ script_dir = Path(__file__).parent
40
+ data_dir = (script_dir / args.data_dir).resolve()
41
+
42
+ print(f"Loading data from: {data_dir}")
43
+
44
+ # Load training data
45
+ train_path = data_dir / 'combined-train.jsonl'
46
+ val_path = data_dir / 'combined-validation.jsonl'
47
+ test_path = data_dir / 'test.jsonl'
48
+
49
+ if not train_path.exists():
50
+ print(f"Error: {train_path} not found")
51
+ return 1
52
+
53
+ train_data = load_jsonl(str(train_path))
54
+ val_data = load_jsonl(str(val_path)) if val_path.exists() else []
55
+ test_data = load_jsonl(str(test_path)) if test_path.exists() else []
56
+
57
+ print(f"Loaded {len(train_data)} train, {len(val_data)} validation, {len(test_data)} test examples")
58
+
59
+ # Create datasets
60
+ def process_examples(examples):
61
+ """Ensure consistent schema."""
62
+ processed = []
63
+ for ex in examples:
64
+ processed.append({
65
+ 'prompt': ex['prompt'],
66
+ 'completion': ex['completion'],
67
+ 'domain': ex.get('metadata', {}).get('domain', 'general'),
68
+ 'complexity': ex.get('metadata', {}).get('complexity', 'medium'),
69
+ 'source': ex.get('metadata', {}).get('source', 'unknown'),
70
+ })
71
+ return processed
72
+
73
+ train_ds = Dataset.from_list(process_examples(train_data))
74
+ val_ds = Dataset.from_list(process_examples(val_data)) if val_data else None
75
+ test_ds = Dataset.from_list(process_examples(test_data)) if test_data else None
76
+
77
+ # Create DatasetDict
78
+ splits = {'train': train_ds}
79
+ if val_ds:
80
+ splits['validation'] = val_ds
81
+ if test_ds:
82
+ splits['test'] = test_ds
83
+
84
+ dataset_dict = DatasetDict(splits)
85
+
86
+ print(f"\nDataset structure:")
87
+ print(dataset_dict)
88
+
89
+ # Create repo if needed
90
+ api = HfApi()
91
+ try:
92
+ create_repo(args.repo, repo_type='dataset', private=args.private, exist_ok=True)
93
+ print(f"\nRepository: https://huggingface.co/datasets/{args.repo}")
94
+ except Exception as e:
95
+ print(f"Note: {e}")
96
+
97
+ # Push to hub
98
+ print(f"\nPushing to HuggingFace Hub...")
99
+ dataset_dict.push_to_hub(
100
+ args.repo,
101
+ private=args.private,
102
+ commit_message="Update training dataset"
103
+ )
104
+
105
+ print(f"\nDataset uploaded successfully!")
106
+ print(f"View at: https://huggingface.co/datasets/{args.repo}")
107
+
108
+ # Create dataset card
109
+ dataset_card = f"""---
110
+ license: apache-2.0
111
+ task_categories:
112
+ - text-generation
113
+ language:
114
+ - en
115
+ tags:
116
+ - orbital
117
+ - schema-generation
118
+ - code
119
+ size_categories:
120
+ - n<1K
121
+ ---
122
+
123
+ # Orbital Schemas Dataset
124
+
125
+ Training data for OrbGen - a model that generates valid Orbital schemas (.orb files).
126
+
127
+ ## Dataset Structure
128
+
129
+ - **train**: {len(train_data)} examples
130
+ - **validation**: {len(val_data)} examples
131
+ - **test**: {len(test_data)} examples
132
+
133
+ ## Features
134
+
135
+ - `prompt`: Natural language description of the desired schema
136
+ - `completion`: Valid Orbital schema in JSON format
137
+ - `domain`: Application domain (ecommerce, game, productivity, etc.)
138
+ - `complexity`: Schema complexity (simple, medium, complex)
139
+ - `source`: Source of the example (synthetic, pattern, integrator)
140
+
141
+ ## Usage
142
+
143
+ ```python
144
+ from datasets import load_dataset
145
+
146
+ dataset = load_dataset("{args.repo}")
147
+ print(dataset["train"][0])
148
+ ```
149
+
150
+ ## Example
151
+
152
+ ```json
153
+ {{
154
+ "prompt": "Create a task management app with projects and due dates",
155
+ "completion": "{{...valid orbital schema...}}",
156
+ "domain": "productivity",
157
+ "complexity": "medium",
158
+ "source": "synthetic"
159
+ }}
160
+ ```
161
+
162
+ ## License
163
+
164
+ Apache 2.0
165
+ """
166
+
167
+ # Save and upload README
168
+ readme_path = data_dir / 'README.md'
169
+ with open(readme_path, 'w') as f:
170
+ f.write(dataset_card)
171
+
172
+ upload_file(
173
+ path_or_fileobj=str(readme_path),
174
+ path_in_repo='README.md',
175
+ repo_id=args.repo,
176
+ repo_type='dataset',
177
+ commit_message='Add dataset card'
178
+ )
179
+
180
+ print(f"Dataset card uploaded!")
181
+ return 0
182
+
183
+
184
+ if __name__ == '__main__':
185
+ exit(main())
scripts/upload_orbital_cli.py ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Upload orbital CLI binary to HuggingFace Hub.
4
+
5
+ Usage:
6
+ # First build the binary:
7
+ cd orbital-rust && cargo build --release --bin orbital
8
+
9
+ # Then upload:
10
+ python scripts/upload_orbital_cli.py
11
+ """
12
+
13
+ import os
14
+ import argparse
15
+ from pathlib import Path
16
+ from huggingface_hub import HfApi, create_repo, upload_file
17
+
18
+
19
+ def main():
20
+ parser = argparse.ArgumentParser(description='Upload orbital CLI to HuggingFace')
21
+ parser.add_argument('--repo', default='orbital-ai/orbital-cli',
22
+ help='HuggingFace repository')
23
+ parser.add_argument('--binary', default=None,
24
+ help='Path to orbital binary (auto-detected if not specified)')
25
+ args = parser.parse_args()
26
+
27
+ # Find binary
28
+ if args.binary:
29
+ binary_path = Path(args.binary)
30
+ else:
31
+ # Try common locations
32
+ candidates = [
33
+ Path.home() / 'kflow.ai.builder/orbital-rust/target/release/orbital',
34
+ Path(__file__).parent.parent.parent.parent / 'orbital-rust/target/release/orbital',
35
+ Path('/home/osamah/kflow.ai.builder/orbital-rust/target/release/orbital'),
36
+ ]
37
+ binary_path = None
38
+ for candidate in candidates:
39
+ if candidate.exists():
40
+ binary_path = candidate
41
+ break
42
+
43
+ if not binary_path:
44
+ print("Error: Could not find orbital binary. Build it first:")
45
+ print(" cd orbital-rust && cargo build --release --bin orbital")
46
+ return 1
47
+
48
+ print(f"Binary: {binary_path}")
49
+ print(f"Size: {binary_path.stat().st_size / 1024 / 1024:.1f} MB")
50
+
51
+ # Create repo
52
+ api = HfApi()
53
+ try:
54
+ create_repo(args.repo, repo_type='model', exist_ok=True)
55
+ print(f"Repository: https://huggingface.co/{args.repo}")
56
+ except Exception as e:
57
+ print(f"Note: {e}")
58
+
59
+ # Upload binary
60
+ print(f"\nUploading to {args.repo}...")
61
+ upload_file(
62
+ path_or_fileobj=str(binary_path),
63
+ path_in_repo='orbital-linux-x86_64',
64
+ repo_id=args.repo,
65
+ commit_message='Upload orbital CLI binary for Linux x86_64'
66
+ )
67
+
68
+ # Create README
69
+ readme = """---
70
+ license: apache-2.0
71
+ tags:
72
+ - orbital
73
+ - cli
74
+ - schema-validation
75
+ ---
76
+
77
+ # Orbital CLI
78
+
79
+ Binary releases of the Orbital CLI for use in training pipelines.
80
+
81
+ ## Files
82
+
83
+ - `orbital-linux-x86_64` - Linux x86_64 binary
84
+
85
+ ## Usage
86
+
87
+ ```bash
88
+ # Download
89
+ wget https://huggingface.co/orbital-ai/orbital-cli/resolve/main/orbital-linux-x86_64 -O orbital
90
+ chmod +x orbital
91
+
92
+ # Validate a schema
93
+ ./orbital validate schema.orb
94
+ ```
95
+
96
+ ## Building from Source
97
+
98
+ ```bash
99
+ cd orbital-rust
100
+ cargo build --release --bin orbital
101
+ ```
102
+ """
103
+
104
+ readme_path = Path('/tmp/orbital-cli-readme.md')
105
+ readme_path.write_text(readme)
106
+
107
+ upload_file(
108
+ path_or_fileobj=str(readme_path),
109
+ path_in_repo='README.md',
110
+ repo_id=args.repo,
111
+ commit_message='Add README'
112
+ )
113
+
114
+ print(f"\nDone! Binary available at:")
115
+ print(f" https://huggingface.co/{args.repo}/resolve/main/orbital-linux-x86_64")
116
+ return 0
117
+
118
+
119
+ if __name__ == '__main__':
120
+ exit(main())
train.py CHANGED
@@ -19,6 +19,7 @@ from transformers import (
19
  AutoTokenizer,
20
  TrainingArguments,
21
  DataCollatorForSeq2Seq,
 
22
  )
23
  from peft import LoraConfig, get_peft_model, TaskType, prepare_model_for_kbit_training
24
  from trl import SFTTrainer, SFTConfig
@@ -93,18 +94,41 @@ def main(
93
  tokenizer.pad_token = tokenizer.eos_token
94
  tokenizer.padding_side = "right"
95
 
96
- # Load model
97
  print("Loading model...")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  model = AutoModelForCausalLM.from_pretrained(
99
  cfg['model']['base_model'],
100
- torch_dtype=torch.bfloat16,
101
- device_map="auto",
102
- trust_remote_code=True,
103
  )
104
 
105
  # Prepare model for training
106
  model.config.use_cache = False
107
- model.enable_input_require_grads()
 
 
 
 
 
108
 
109
  # Configure LoRA
110
  if cfg['lora']['enabled']:
@@ -122,10 +146,22 @@ def main(
122
 
123
  # Load dataset
124
  print("\nLoading dataset...")
125
- dataset = load_dataset(cfg['data']['dataset'])
126
 
127
- train_dataset = dataset[cfg['data']['train_split']]
128
- eval_dataset = dataset[cfg['data']['eval_split']]
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
  print(f"Train examples: {len(train_dataset)}")
131
  print(f"Eval examples: {len(eval_dataset)}")
@@ -175,19 +211,19 @@ def main(
175
  bf16=True,
176
  gradient_checkpointing=True,
177
  gradient_checkpointing_kwargs={"use_reentrant": False},
178
- max_seq_length=cfg['model']['max_seq_length'],
179
  dataset_text_field="text",
180
  report_to="wandb" if not debug else "none",
181
  max_steps=max_steps if max_steps > 0 else -1,
182
  )
183
 
184
- # Create trainer
185
  trainer = SFTTrainer(
186
  model=model,
187
  args=training_args,
188
  train_dataset=train_dataset,
189
  eval_dataset=eval_dataset,
190
- tokenizer=tokenizer,
191
  )
192
 
193
  # Train
@@ -199,6 +235,14 @@ def main(
199
  trainer.save_model(f"{cfg['model']['output_dir']}/final")
200
  tokenizer.save_pretrained(f"{cfg['model']['output_dir']}/final")
201
 
 
 
 
 
 
 
 
 
202
  # Finish wandb
203
  if not debug:
204
  wandb.finish()
 
19
  AutoTokenizer,
20
  TrainingArguments,
21
  DataCollatorForSeq2Seq,
22
+ BitsAndBytesConfig,
23
  )
24
  from peft import LoraConfig, get_peft_model, TaskType, prepare_model_for_kbit_training
25
  from trl import SFTTrainer, SFTConfig
 
94
  tokenizer.pad_token = tokenizer.eos_token
95
  tokenizer.padding_side = "right"
96
 
97
+ # Load model with optional quantization
98
  print("Loading model...")
99
+
100
+ model_kwargs = {
101
+ "trust_remote_code": True,
102
+ "device_map": "auto",
103
+ }
104
+
105
+ # Check if 4-bit quantization is enabled
106
+ quant_cfg = cfg.get('quantization', {})
107
+ if quant_cfg.get('enabled', False) and quant_cfg.get('load_in_4bit', False):
108
+ print("Using 4-bit quantization (QLoRA)...")
109
+ bnb_config = BitsAndBytesConfig(
110
+ load_in_4bit=True,
111
+ bnb_4bit_compute_dtype=getattr(torch, quant_cfg.get('bnb_4bit_compute_dtype', 'bfloat16')),
112
+ bnb_4bit_quant_type=quant_cfg.get('bnb_4bit_quant_type', 'nf4'),
113
+ bnb_4bit_use_double_quant=quant_cfg.get('bnb_4bit_use_double_quant', True),
114
+ )
115
+ model_kwargs["quantization_config"] = bnb_config
116
+ else:
117
+ model_kwargs["torch_dtype"] = torch.bfloat16
118
+
119
  model = AutoModelForCausalLM.from_pretrained(
120
  cfg['model']['base_model'],
121
+ **model_kwargs,
 
 
122
  )
123
 
124
  # Prepare model for training
125
  model.config.use_cache = False
126
+
127
+ # For quantized models, use prepare_model_for_kbit_training
128
+ if quant_cfg.get('enabled', False):
129
+ model = prepare_model_for_kbit_training(model)
130
+ else:
131
+ model.enable_input_require_grads()
132
 
133
  # Configure LoRA
134
  if cfg['lora']['enabled']:
 
146
 
147
  # Load dataset
148
  print("\nLoading dataset...")
 
149
 
150
+ # Support both HuggingFace dataset and local files
151
+ if 'train_file' in cfg['data']:
152
+ # Load from local JSONL files
153
+ data_files = {
154
+ 'train': cfg['data']['train_file'],
155
+ 'validation': cfg['data']['eval_file'],
156
+ }
157
+ dataset = load_dataset('json', data_files=data_files)
158
+ train_dataset = dataset['train']
159
+ eval_dataset = dataset['validation']
160
+ else:
161
+ # Load from HuggingFace Hub
162
+ dataset = load_dataset(cfg['data']['dataset'])
163
+ train_dataset = dataset[cfg['data']['train_split']]
164
+ eval_dataset = dataset[cfg['data']['eval_split']]
165
 
166
  print(f"Train examples: {len(train_dataset)}")
167
  print(f"Eval examples: {len(eval_dataset)}")
 
211
  bf16=True,
212
  gradient_checkpointing=True,
213
  gradient_checkpointing_kwargs={"use_reentrant": False},
214
+ max_length=cfg['model']['max_seq_length'],
215
  dataset_text_field="text",
216
  report_to="wandb" if not debug else "none",
217
  max_steps=max_steps if max_steps > 0 else -1,
218
  )
219
 
220
+ # Create trainer (TRL v0.27+ API)
221
  trainer = SFTTrainer(
222
  model=model,
223
  args=training_args,
224
  train_dataset=train_dataset,
225
  eval_dataset=eval_dataset,
226
+ processing_class=tokenizer,
227
  )
228
 
229
  # Train
 
235
  trainer.save_model(f"{cfg['model']['output_dir']}/final")
236
  tokenizer.save_pretrained(f"{cfg['model']['output_dir']}/final")
237
 
238
+ # Push to HuggingFace Hub if configured
239
+ hub_cfg = cfg.get('hub', {})
240
+ if hub_cfg.get('push_to_hub', False) and not debug:
241
+ print("\nPushing model to HuggingFace Hub...")
242
+ hub_model_id = hub_cfg.get('hub_model_id', 'orbital-ai/orbgen-1.5b')
243
+ trainer.push_to_hub(commit_message="Final model after SFT training")
244
+ print(f"Model pushed to: https://huggingface.co/{hub_model_id}")
245
+
246
  # Finish wandb
247
  if not debug:
248
  wandb.finish()