# ONNX Runtime GPU

> **क्रॉस-प्लेटफ़ॉर्म, हार्डवेयर-त्वरित ML इन्फ़रेंस — किसी भी फ्रेमवर्क के किसी भी मॉडल को तैनात करें**

ONNX Runtime (ORT) माइक्रोसॉफ्ट का ओपन-सोर्स इनफ़रेंस इंजन है जो ONNX (Open Neural Network Exchange) मॉडलों के लिए है। यह एक एकीकृत API के माध्यम से CPU, GPU, और विशेष एसेलेरेटर पर हार्डवेयर-त्वरित इनफ़रेंस प्रदान करता है। चाहे आपका मॉडल PyTorch, TensorFlow, Scikit-learn, या XGBoost में प्रशिक्षित किया गया हो — यदि आप इसे ONNX फॉर्मेट में एक्सपोर्ट कर सकते हैं, तो ORT इसे तेज़ी से चला सकता है।

**GitHub:** [microsoft/onnxruntime](https://github.com/microsoft/onnxruntime) — 14K+ ⭐

***

## क्यों ONNX Runtime?

| फ़ीचर                   | TensorRT-LLM      | TorchScript    | TensorFlow Serving |
| ----------------------- | ----------------- | -------------- | ------------------ |
| फ्रेमवर्क-अज्ञेय        | ✅                 | ❌ केवल PyTorch | ❌ केवल TF          |
| GPU त्वरण               | ✅ CUDA/TensorRT   | ✅              | ✅                  |
| INT8/FP16 क्वांटाइज़ेशन | ✅                 | आंशिक          | आंशिक              |
| मोबाइल/एज पर तैनाती     | ✅                 | सीमित          | सीमित              |
| ऑपरेटर फ़्यूज़न         | ✅                 | आंशिक          | ✅                  |
| आसान एकीकरण             | ✅ Python/C++/Java | Python         | Python/gRPC        |

{% hint style="success" %}
**मुख्य लाभ:** CUDA execution provider के साथ ONNX Runtime सामान्यतः प्रदान करता है **1.5–3x गति वृद्धि** कम्प्यूटर विज़न और NLP मॉडलों के लिए नेटिव PyTorch इनफ़रेंस की तुलना में।
{% endhint %}

***

## समर्थित Execution Providers

ONNX Runtime कई हार्डवेयर बैकएंड्स (Execution Providers) का समर्थन करता है:

| प्रोवाइडर                   | हार्डवेयर     | उपयोग केस            |
| --------------------------- | ------------- | -------------------- |
| `CUDAExecutionProvider`     | NVIDIA GPUs   | सामान्य GPU इनफ़रेंस |
| `TensorrtExecutionProvider` | NVIDIA GPUs   | अधिकतम थ्रूपुट       |
| `CPUExecutionProvider`      | CPU           | फॉलबैक / एज          |
| `ROCMExecutionProvider`     | AMD GPUs      | AMD हार्डवेयर        |
| `CoreMLExecutionProvider`   | Apple Silicon | macOS/iOS            |
| `OpenVINOExecutionProvider` | Intel         | Intel CPUs/GPUs      |

***

## पूर्व-आवश्यकताएँ

* GPU किराए के साथ Clore.ai खाता
* बुनियादी Python ज्ञान
* एक प्रशिक्षित मॉडल (PyTorch, TensorFlow, या पहले से एक्सपोर्ट किया गया ONNX)

***

## चरण 1 — Clore.ai पर एक GPU किराए पर लें

1. जाएँ [clore.ai](https://clore.ai) → **मार्केटप्लेस**
2. कोई भी NVIDIA GPU काम करेगा — छोटे मॉडलों के लिए RTX 3070 से लेकर बड़े ट्रांसफ़ॉर्मर्स के लिए A100 तक
3. **ट्रांसफ़ॉर्मर मॉडलों के लिए:** RTX 4090 या A100 की सिफारिश की जाती है
4. **कम्प्यूटर विज़न के लिए:** RTX 3090 या RTX 4090 पर्याप्त है

***

## चरण 2 — अपना कंटेनर तैनात करें

ONNX Runtime का कोई आधिकारिक pre-built कंटेनर नहीं है, लेकिन NVIDIA CUDA बेस आदर्श है:

**Docker इमेज:**

```
nvcr.io/nvidia/cuda:12.2.0-cudnn8-devel-ubuntu22.04
```

**पोर्ट्स:**

```
22
```

**पर्यावरण चर:**

```
NVIDIA_VISIBLE_DEVICES=all
NVIDIA_DRIVER_CAPABILITIES=compute,utility
```

{% hint style="info" %}
वैकल्पिक रूप से, उपयोग करें `pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime` जिसमें CUDA और ORT इंस्टॉलेशन के लिए तैयार Python एनवायरनमेंट शामिल है।
{% endhint %}

***

## चरण 3 — GPU समर्थन के साथ ONNX Runtime इंस्टॉल करें

```bash
ssh root@<server-ip> -p <ssh-port>

# पैकेज अपडेट करें
apt-get update && apt-get install -y \
    python3-pip \
    python3-dev \
    wget \
    git \
    libgomp1

# CUDA समर्थन के साथ ONNX Runtime इंस्टॉल करें
pip install onnxruntime-gpu

# सहायक पैकेज इंस्टॉल करें
pip install \
    onnx \
    numpy \
    Pillow \
    transformers \
    torch \
    torchvision \
    fastapi \
    uvicorn

# स्थापना सत्यापित करें
python3 << 'EOF'
import onnxruntime as ort
print(f"ORT Version: {ort.__version__}")
print(f"Available providers: {ort.get_available_providers()}")
# इसमें शामिल होना चाहिए: CUDAExecutionProvider, TensorrtExecutionProvider, CPUExecutionProvider
EOF
```

***

## चरण 4 — अपना मॉडल ONNX में एक्सपोर्ट करें

### PyTorch मॉडल एक्सपोर्ट

```python
import torch
import torch.nn as nn
import onnx

# उदाहरण: ResNet50 एक्सपोर्ट करें
model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet50', pretrained=True)
model.eval()

# डमी इनपुट बनाएं (batch=1, RGB इमेज 224x224)
dummy_input = torch.randn(1, 3, 224, 224)

# ONNX में एक्सपोर्ट करें
torch.onnx.export(
    model,
    dummy_input,
    "resnet50.onnx",
    export_params=True,
    opset_version=17,              # नवीनतम स्थिर opset का उपयोग करें
    do_constant_folding=True,      # स्थिर मानों का अनुकूलन करें
    input_names=["input"],
    output_names=["output"],
    dynamic_axes={
        "input": {0: "batch_size"},    # डायनैमिक बैच
        "output": {0: "batch_size"}
    }
)
print("Model exported successfully!")

# एक्सपोर्ट किए गए मॉडल को सत्यापित करें
onnx_model = onnx.load("resnet50.onnx")
onnx.checker.check_model(onnx_model)
print("ONNX model is valid!")
```

### HuggingFace Transformers एक्सपोर्ट

```bash
# HuggingFace ONNX एक्सपोर्ट के लिए optimum इंस्टॉल करें
pip install optimum[exporters]

# टेक्स्ट क्लासिफिकेशन के लिए BERT एक्सपोर्ट करें
optimum-cli export onnx \
    --model bert-base-uncased \
    --task text-classification \
    ./bert_onnx/

# अनुकूलन के साथ एक्सपोर्ट करें
optimum-cli export onnx \
    --model microsoft/phi-2 \
    --task text-generation \
    --optimize O2 \
    ./phi2_onnx/
```

### ORT अनुकूलन के साथ एक्सपोर्ट करें

```python
from optimum.onnxruntime import ORTModelForSequenceClassification
from optimum.onnxruntime.configuration import OptimizationConfig, ORTConfig
from optimum.onnxruntime import ORTOptimizer

# लोड और अनुकूलित करें
model = ORTModelForSequenceClassification.from_pretrained(
    "distilbert-base-uncased-finetuned-sst-2-english",
    export=True
)

optimizer = ORTOptimizer.from_pretrained(model)
optimization_config = OptimizationConfig(
    optimization_level=2,
    optimize_for_gpu=True,
    fp16=True
)

optimizer.optimize(
    save_dir="./distilbert_optimized",
    optimization_config=optimization_config
)
```

***

## चरण 5 — ONNX Runtime के साथ इनफ़रेंस चलाएँ

### बुनियादी GPU इनफ़रेंस

```python
import onnxruntime as ort
import numpy as np
from PIL import Image
import torchvision.transforms as transforms

# GPU execution providers के साथ सेशन कॉन्फ़िगर करें
# प्रोवाइडर्स को क्रम में आजमाया जाता है — पहले CUDA, फिर CPU फॉलबैक
providers = [
    ("CUDAExecutionProvider", {
        "device_id": 0,
        "arena_extend_strategy": "kNextPowerOfTwo",
        "gpu_mem_limit": 4 * 1024 * 1024 * 1024,  # 4GB सीमा
        "cudnn_conv_algo_search": "EXHAUSTIVE",
        "do_copy_in_default_stream": True,
    }),
    "CPUExecutionProvider"
]

# प्रदर्शन के लिए सेशन विकल्प
opts = ort.SessionOptions()
opts.graph_optimization_level = ort.GraphOptimizationLevel.ORT_ENABLE_ALL
opts.intra_op_num_threads = 8
opts.execution_mode = ort.ExecutionMode.ORT_PARALLEL

# मॉडल लोड करें
session = ort.InferenceSession(
    "resnet50.onnx",
    sess_options=opts,
    providers=providers
)

print(f"Running on: {session.get_providers()}")

# इनपुट तैयार करें
transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

img = Image.open("test_image.jpg").convert("RGB")
img_tensor = transform(img).unsqueeze(0).numpy()

# इन्फरेंस चलाएँ
outputs = session.run(None, {"input": img_tensor})
probabilities = outputs[0][0]
top5_idx = probabilities.argsort()[-5:][::-1]
print("Top 5 predictions:", top5_idx, probabilities[top5_idx])
```

### थ्रूपुट के लिए बैच इनफ़रेंस

```python
import onnxruntime as ort
import numpy as np
import time

session = ort.InferenceSession(
    "resnet50.onnx",
    providers=["CUDAExecutionProvider"]
)

# GPU वार्म अप करें
dummy = np.random.randn(1, 3, 224, 224).astype(np.float32)
for _ in range(10):
    session.run(None, {"input": dummy})

# बैच साइज़ का बेंचमार्क करें
for batch_size in [1, 4, 8, 16, 32, 64]:
    inputs = np.random.randn(batch_size, 3, 224, 224).astype(np.float32)
    
    start = time.time()
    n_iter = 100
    for _ in range(n_iter):
        session.run(None, {"input": inputs})
    elapsed = time.time() - start
    
    throughput = (batch_size * n_iter) / elapsed
    latency = (elapsed / n_iter) * 1000  # ms
    
    print(f"Batch {batch_size:3d}: {throughput:7.1f} img/sec, {latency:.1f}ms/batch")
```

***

## चरण 6 — TensorRT Execution Provider (अधिकतम प्रदर्शन)

NVIDIA GPUs के लिए, TensorRT EP और भी बेहतर प्रदर्शन प्रदान करता है:

```python
import onnxruntime as ort
import numpy as np

# TensorRT execution provider कॉन्फ़िगरेशन
tensorrt_provider_options = {
    "trt_max_workspace_size": 4 * 1024 * 1024 * 1024,  # 4GB
    "trt_fp16_enable": True,          # तेज़ इनफ़रेंस के लिए FP16 सक्षम करें
    "trt_int8_enable": False,
    "trt_engine_cache_enable": True,   # संकलित इंजनों को कैश करें
    "trt_engine_cache_path": "/tmp/trt_cache",
    "trt_max_partition_iterations": 1000,
    "trt_min_subgraph_size": 1,
    "trt_timing_cache_enable": True,
}

providers = [
    ("TensorrtExecutionProvider", tensorrt_provider_options),
    ("CUDAExecutionProvider", {"device_id": 0}),
    "CPUExecutionProvider"
]

session = ort.InferenceSession("resnet50.onnx", providers=providers)
print("Active provider:", session.get_providers()[0])

# पहली रन TensorRT इंजन को संकलित करती है (1-3 मिनट लग सकते हैं)
# बाद की रन कैश किए गए इंजन का उपयोग करती हैं और बहुत तेज़ होती हैं
```

{% hint style="warning" %}
**TensorRT इंजन का संकलन** पहली इनफ़रेंस पर होता है और 1–5 मिनट तक लग सकता है। कैशिंग सक्षम करें (`trt_engine_cache_enable: True`) ताकि संकलित इंजन को सेशंस के बीच पुन: उपयोग किया जा सके।
{% endhint %}

***

## चरण 7 — अधिकतम गति के लिए INT8 क्वांटाइज़ेशन

```python
from onnxruntime.quantization import quantize_dynamic, quantize_static, QuantType
import onnxruntime as ort
import numpy as np

# डायनामिक INT8 क्वांटाइज़ेशन (कैलिब्रेशन डाटा की आवश्यकता नहीं)
quantize_dynamic(
    model_input="resnet50.onnx",
    model_output="resnet50_int8_dynamic.onnx",
    weight_type=QuantType.QInt8
)

# स्टेटिक INT8 क्वांटाइज़ेशन (कैलिब्रेशन डाटा आवश्यक है)
from onnxruntime.quantization import CalibrationDataReader

class ImageCalibrationReader(CalibrationDataReader):
    def __init__(self, data_dir, input_name="input"):
        self.data_dir = data_dir
        self.input_name = input_name
        self.images = self._load_images()
        self.idx = 0
    
    def _load_images(self):
        # 100 कैलिब्रेशन इमेज लोड करें
        import glob, torchvision.transforms as T
        from PIL import Image
        transform = T.Compose([T.Resize(256), T.CenterCrop(224), T.ToTensor()])
        images = []
        for path in glob.glob(f"{self.data_dir}/*.jpg")[:100]:
            img = Image.open(path).convert("RGB")
            images.append(transform(img).numpy())
        return images
    
    def get_next(self):
        if self.idx >= len(self.images):
            return None
        data = {self.input_name: self.images[self.idx:self.idx+1]}
        self.idx += 1
        return data

from onnxruntime.quantization import quantize_static, QuantFormat
quantize_static(
    model_input="resnet50.onnx",
    model_output="resnet50_int8_static.onnx",
    calibration_data_reader=ImageCalibrationReader("/data/calibration_images"),
    quant_format=QuantFormat.QDQ,
    weight_type=QuantType.QInt8
)
```

***

## चरण 8 — एक Inference API बनाएं

```bash
cat > /workspace/onnx_api.py << 'EOF'
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import JSONResponse
import onnxruntime as ort
import numpy as np
from PIL import Image
import io
import torchvision.transforms as transforms
import json

app = FastAPI(title="ONNX Runtime Inference API")

# स्टार्टअप पर मॉडल लोड करें
session = ort.InferenceSession(
    "resnet50.onnx",
    providers=["CUDAExecutionProvider", "CPUExecutionProvider"]
)

# ImageNet क्लास लेबल लोड करें
with open("imagenet_classes.json") as f:
    classes = json.load(f)

transform = transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

@app.get("/health")
async def health():
    return {"status": "ok", "providers": session.get_providers()}

@app.post("/predict")
async def predict(file: UploadFile = File(...), topk: int = 5):
    image_data = await file.read()
    img = Image.open(io.BytesIO(image_data)).convert("RGB")
    tensor = transform(img).unsqueeze(0).numpy()
    
    outputs = session.run(None, {"input": tensor})[0][0]
    top_indices = outputs.argsort()[-topk:][::-1]
    
    results = [
        {"label": classes[str(i)], "score": float(outputs[i])}
        for i in top_indices
    ]
    return JSONResponse({"predictions": results})

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8080)
EOF

python3 /workspace/onnx_api.py &

# API का परीक्षण करें
curl -X POST "http://localhost:8080/predict" \
    -H "accept: application/json" \
    -F "file=@test_image.jpg"
```

***

## चरण 9 — GPU उपयोग की निगरानी करें

```bash
# इनफ़रेंस के दौरान रियल-टाइम GPU मॉनिटरिंग
watch -n 0.5 nvidia-smi

# या बेहतर UI के लिए nvitop का उपयोग करें
pip install nvitop
nvitop
```

***

## प्रदर्शन बेंचमार्क्स

| मॉडल     | GPU      | प्रोवाइडर     | थ्रूपुट (inf/sec) |
| -------- | -------- | ------------- | ----------------- |
| ResNet50 | RTX 4090 | CUDA          | \~4,200           |
| ResNet50 | RTX 4090 | TensorRT FP16 | \~8,500           |
| BERT बेस | RTX 4090 | CUDA          | \~380             |
| BERT बेस | RTX 4090 | TensorRT FP16 | \~720             |
| YOLOv8n  | RTX 3090 | CUDA          | \~1,800           |
| YOLOv8x  | A100     | TensorRT FP16 | \~920             |

***

## समस्या निवारण

### CUDA प्रोवाइडर उपलब्ध नहीं है

```bash
# जांचें कि CUDA ORT इंस्टॉल है (केवल CPU वर्ज़न नहीं)
pip uninstall onnxruntime
pip install onnxruntime-gpu

python3 -c "import onnxruntime as ort; print(ort.get_available_providers())"
```

### TensorRT संकलन त्रुटियाँ

```bash
# TensorRT संस्करण संगतता जांचें
python3 -c "import tensorrt; print(tensorrt.__version__)"

# इसके बजाय CUDA EP का उपयोग करें
providers = ["CUDAExecutionProvider"]  # TensorRT EP छोड़ें
```

### आकार मेल न होने की त्रुटियाँ

```python
# मॉडल इनपुट/आउटपुट आकार जांचें
for input in session.get_inputs():
    print(f"Input: {input.name}, shape: {input.shape}, type: {input.type}")

for output in session.get_outputs():
    print(f"Output: {output.name}, shape: {output.shape}, type: {output.type}")
```

***

## उन्नत: मल्टी-मॉडल पाइपलाइन

```python
import onnxruntime as ort
import numpy as np

class MultiModelPipeline:
    def __init__(self):
        providers = ["CUDAExecutionProvider"]
        self.detector = ort.InferenceSession("detector.onnx", providers=providers)
        self.classifier = ort.InferenceSession("classifier.onnx", providers=providers)
    
    def run(self, image: np.ndarray) -> list:
        # स्टेज 1: ऑब्जेक्ट डिटेक्शन
        boxes = self.detector.run(None, {"image": image})[0]
        
        results = []
        for box in boxes:
            # पहचानित क्षेत्र को क्रॉप करें
            crop = self._crop(image, box)
            
            # स्टेज 2: प्रत्येक क्षेत्र को क्लासिफाई करें
            label = self.classifier.run(None, {"input": crop})[0]
            results.append({"box": box.tolist(), "label": int(label.argmax())})
        
        return results
    
    def _crop(self, image, box):
        x1, y1, x2, y2 = box.astype(int)
        return image[:, :, y1:y2, x1:x2]

pipeline = MultiModelPipeline()
```

***

## अतिरिक्त संसाधन

* [ONNX Runtime GitHub](https://github.com/microsoft/onnxruntime)
* [ONNX Runtime प्रलेखन](https://onnxruntime.ai/docs/)
* [Hugging Face Optimum](https://huggingface.co/docs/optimum/)
* [ONNX Model Zoo](https://github.com/onnx/models) — पहले से एक्सपोर्ट किए गए मॉडल
* [Netron](https://netron.app/) — ONNX मॉडल विज़ुअलाइज़र
* [ONNX Runtime Python API](https://onnxruntime.ai/docs/api/python/)

***

*Clore.ai पर ONNX Runtime उत्पादन इनफ़रेंस सेवाओं के लिए आदर्श विकल्प है जिन्हें अधिकतम GPU दक्षता के साथ विभिन्न फ्रेमवर्क्स के मॉडल सर्व करने की आवश्यकता होती है।*

***

## Clore.ai GPU सिफारिशें

| उपयोग केस             | सिफारिश की गई GPU | Clore.ai पर अनुमानित लागत |
| --------------------- | ----------------- | ------------------------- |
| डेवलपमेंट/टेस्टिंग    | RTX 3090 (24GB)   | \~$0.12/gpu/hr            |
| उत्पादन इन्फरेंस      | RTX 4090 (24GB)   | \~$0.70/gpu/hr            |
| बड़े पैमाने पर तैनाती | A100 80GB         | \~$1.20/gpu/hr            |

> 💡 इस गाइड के सभी उदाहरण तैनात किए जा सकते हैं [Clore.ai](https://clore.ai/marketplace) GPU सर्वरों पर। उपलब्ध GPUs ब्राउज़ करें और घंटे के हिसाब से किराए पर लें — कोई प्रतिबद्धता नहीं, पूर्ण रूट एक्सेस।
