Skip to content

Commit 9b1fd34

Browse files
committed
Update model upload readme
1 parent c11a5e0 commit 9b1fd34

File tree

2 files changed

+338
-34
lines changed

2 files changed

+338
-34
lines changed

models/model_upload/README.md

Lines changed: 147 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@
66
77
This guide will walk you through the process of uploading custom models to the Clarifai platform, leveraging pre-built model examples for different tasks. You'll also learn to customize models and adjust configurations for deployment.
88

9+
## Contents
10+
11+
- [Clarifai Model Upload](#clarifai-model-upload)
12+
- [Contents](#contents)
13+
- [Available Model Examples](#available-model-examples)
14+
- [Installation](#installation)
15+
- [Environment Setup](#environment-setup)
16+
- [Model Folder Structure](#model-folder-structure)
17+
- [Example Directory Structure:](#example-directory-structure)
18+
- [Model Upload Guide](#model-upload-guide)
19+
- [Step 1: Define the `config.yaml` File](#step-1-define-the-configyaml-file)
20+
- [Model Info](#model-info)
21+
- [Compute Resources](#compute-resources)
22+
- [Model Checkpoints](#model-checkpoints)
23+
- [Model concepts/ labels](#model-concepts-labels)
24+
- [Step 2: Define dependencies in requirements.txt](#step-2-define-dependencies-in-requirementstxt)
25+
- [Step 3: Prepare the `model.py` File](#step-3-prepare-the-modelpy-file)
26+
- [Core Model Class Structure\*\*](#core-model-class-structure)
27+
- [Example Class Structure:](#example-class-structure)
28+
- [load\_model() (Optional):](#load_model-optional)
29+
- [Method Decorators](#method-decorators)
30+
- [Supported Input and Output Data Types](#supported-input-and-output-data-types)
31+
- [Step 4: Test Model locally](#step-4-test-model-locally)
32+
- [Testing the Model in a Container](#testing-the-model-in-a-container)
33+
- [Testing the Model in a Virtual Environment](#testing-the-model-in-a-virtual-environment)
34+
- [2. Running the Model Locally](#2-running-the-model-locally)
35+
- [Running the Model in a Docker Container](#running-the-model-in-a-docker-container)
36+
- [Running the Model in a Virtual Environment](#running-the-model-in-a-virtual-environment)
37+
- [Making Inference Requests to the Running Model](#making-inference-requests-to-the-running-model)
38+
- [unary-unary predict call](#unary-unary-predict-call)
39+
- [CLI flags](#cli-flags)
40+
- [Step 5: Upload the Model to Clarifai](#step-5-upload-the-model-to-clarifai)
41+
- [Step 6: Model Prediction](#step-6-model-prediction)
42+
- [unary-unary predict call](#unary-unary-predict-call-1)
43+
- [unary-stream predict call](#unary-stream-predict-call)
44+
- [stream-stream predict call](#stream-stream-predict-call)
45+
946
### Available Model Examples
1047
Clarifai provides a collection of pre-built model examples designed for different tasks. You can leverage these examples to streamline the model upload and deployment process.
1148

@@ -100,8 +137,21 @@ checkpoints:
100137
type: "huggingface"
101138
repo_id: "meta-llama/Meta-Llama-3-8B-Instruct"
102139
hf_token: "your_hf_token" # Required for private models
140+
when: "runtime"
103141
```
104142

143+
> `when` in the checkpoints section defines when checkpoints for the model should be downloaded and stored. The `when` parameter must be one of `['upload', 'build', 'runtime']`. 
144+
>
145+
> * **runtime**: Downloads checkpoints at runtime when loading the model in the `load_model` method.
146+
> * **build**: Downloads checkpoints at build time, while the image is being built.
147+
> * **upload**: Downloads checkpoints before uploading the model.
148+
>
149+
> For larger models, we highly recommend downloading checkpoints at `runtime`. Downloading them during the `upload` or `build` stages can significantly increase the Docker image size, leading to longer upload times and increased cold start time for the model. while downloading checkpoints at `runtime` has some advantages:
150+
>
151+
> * Smaller image sizes
152+
> * Faster build times
153+
> * Faster pushes and inference on Clarifai platform
154+
105155
#### Model concepts/ labels
106156
> Important: This section is necessary if your model outputs concepts/labels (e.g., for classification or detection) and is not directly loaded from Hugging Face.
107157

@@ -124,38 +174,101 @@ concepts:
124174
### Step 2: Define dependencies in requirements.txt
125175
List all required Python dependencies for your model in `requirements.txt` file. This ensures that all necessary libraries are installed in the runtime environment
126176

177+
178+
> If your model requires `Torch`, we provide optimized pre-built Torch images as the base for machine learning and inference tasks. These images include all necessary dependencies, ensuring efficient execution. 
179+
>
180+
>
181+
> The available pre-built Torch images are:
182+
> • `2.4.1-py3.11-cuda124`: Based on PyTorch 2.4.1, Python 3.11, and CUDA 12.4.
183+
> • `2.5.1-py3.11-cuda124`: Based on PyTorch 2.5.1, Python 3.11, and CUDA 12.4.
184+
> • `2.4.1-py3.12-cuda124`: Based on PyTorch 2.4.1, Python 3.12, and CUDA 12.4.
185+
> • `2.5.1-py3.12-cuda124`: Based on PyTorch 2.5.1, Python 3.12, and CUDA 12.4.
186+
>
187+
> To use a specific Torch version, define it in your `requirements.txt` file like this: `torch==2.5.1` This ensures the correct pre-built image is pulled from Clarifai's container registry, ensuring the correct environment is used. This minimizes cold start times and speeds up model uploads and runtime execution — avoiding the overhead of building images from scratch or pulling and configuring them from external sources.
188+
> We recommend using either `torch==2.5.1` or `torch==2.4.1`. If your model requires a different Torch version, you can specify it in requirements.txt, but this may slightly increase the model upload time.
189+
127190
### Step 3: Prepare the `model.py` File
128191

129-
The `model.py` file contains the logic for your model, including how the model is loaded and how predictions are made. This file must implement a class that inherits from `ModelRunner`, which should define the following methods:
192+
The `model.py` file contains the logic for your model, including how the model is loaded and how predictions are made. This file must implement a class that inherits from `ModelClass`.
193+
194+
### Core Model Class Structure**
195+
196+
To define a custom model, you need to create a class that inherits from **ModelClass** and implements the **load\_model** method and at least one method decorated with **@ModelClass.method** to define prediction endpoints
197+
198+
> Each parameter of the Class method must be annotated with a type. The method's return type must also be annotated. The supported types are described [here](SUPPORTED_DATATYPE.md):
130199

131200
#### Example Class Structure:
132201

133202
```python
134203
from clarifai.runners.models.model_class import ModelClass
135-
from clarifai.runners.models.model_builder import ModelBuilder
204+
from clarifai.runners.utils.data_types import Stream, Text
205+
206+
207+
class MyModel(ModelClass):
208+
"""A custom runner that adds "Hello World" to the end of the text."""
136209
137-
class YourCustomModel(ModelClass):
138210
def load_model(self):
139-
'''Initialize and load the model here'''
140-
pass
211+
"""Load the model here."""
212+
213+
@ModelClass.method
214+
def predict(self, text1: Text = "") -> Text:
215+
"""This is the method that will be called when the runner is run. It takes in an input and
216+
returns an output.
217+
"""
218+
219+
output_text = text1.text + "Hello World"
220+
221+
return Text(output_text)
222+
223+
@ModelClass.method
224+
def generate(self, text1: Text = Text("")) -> Stream[Text]:
225+
"""Example yielding a whole batch of streamed stuff back."""
226+
227+
for i in range(10): # fake something iterating generating 10 times.
228+
output_text = text1.text + f"Generate Hello World {i}"
229+
yield Text(output_text)
230+
231+
@ModelClass.method
232+
def stream(self, input_iterator: Stream[Text]) -> Stream[Text]:
233+
"""Example yielding a whole batch of streamed stuff back."""
234+
235+
for i, input in enumerate(input_iterator):
236+
output_text = input.text + f"Stream Hello World {i}"
237+
yield Text(output_text)
238+
```
239+
240+
#### load\_model() (Optional):
241+
242+
Use this _optional_ method to include any expensive one-off operations in here like loading trained models, instantiate data transformations, etc.
243+
244+
* One-time initialization of heavy resources
245+
* Called during model container startup
246+
* Ideal for loading model:
247+
248+
```python
249+
def load_model(self):
250+
self.tokenizer = AutoTokenizer.from_pretrained("model/")
251+
self.pipeline = transformers.pipeline(...)
252+
```
253+
254+
#### Method Decorators
141255

142-
def predict(self, request):
143-
'''Define logic to handle input and return output'''
144-
return output_data
256+
* **@ModelClass.method** registers prediction endpoints
257+
* Supports three method types via type hints:
145258

146-
def generate(self, request):
147-
'''Define streaming output logic if needed'''
148-
pass
259+
```python
260+
# Unary-Unary (Standard request-response)
261+
def predict(self, input: Image) -> Text
262+
263+
# Unary-Stream (Server-side streaming)
264+
def generate(self, prompt: Text) -> Stream[Text]
149265
150-
def stream(self, request):
151-
'''Handle both streaming input and output'''
152-
pass
266+
# Stream-Stream (Bidirectional streaming)
267+
def analyze_video(self, frames: Stream[Image]) -> Stream[str]
153268
```
154269

155-
* **load_model()**: Loads the model, similar to an initialization step.
156-
* **predict(input_data)**: Handles the core logic for making a prediction with the model. It processes input data and returns a output reponse.
157-
* **generate(input_data)**: Returns output in a streaming manner (if applicable).
158-
* **stream(input_data)**: Manages streaming input and output (for more advanced use cases).
270+
#### [Supported Input and Output Data Types](SUPPORTED_DATATYPE.md)
271+
Clarifai's model framework supports rich data typing for both inputs and outputs. [Here](SUPPORTED_DATATYPE.md) is a comprehensive guide to supported types with usage examples.
159272

160273
### Step 4: Test Model locally
161274

@@ -171,14 +284,12 @@ This method runs the model locally and sends a sample request to verify that the
171284

172285
This method runs the model locally and starts a local gRPC server at \`https://localhost:{port}\`, Once the server is running, you can perform inference on the model via the Clarifai client SDK
173286

174-
175287
You can test the model within a Docker container or a Python virtual environment.
176288

177289
> **Recommendation:** If Docker is installed on your system, it is highly recommended to use Docker for testing or running the model, as it provides better isolation and avoids dependency conflicts.
178290

179291
1. ### Testing the Model
180292

181-
182293
#### Testing the Model in a Container
183294

184295
```python
@@ -250,7 +361,7 @@ clarifai model upload --model_path {model_directory_path}
250361
This command builds the model Docker image based on the specified compute resources and uploads it to the Clarifai platform.
251362

252363

253-
### Model Prediction
364+
### Step 6: Model Prediction
254365

255366
Once the model is uploaded, you can easily make the prediction to the model using Clarifai SDK.
256367

@@ -260,35 +371,37 @@ Once the model is uploaded, you can easily make the prediction to the model usin
260371

261372
```python
262373
from clarifai.client.model import Model
263-
model = Model("url") # Example URL: https://clarifai.com/stepfun-ai/ocr/models/got-ocr-2_0
374+
model = Model("url", , compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
264375
or
265-
model = Model(model_id='model_id', user_id='user_id', app_id='app_id')
266-
267-
image_url = "https://samples.clarifai.com/metro-north.jpg"
376+
model = Model(model_id='model_id', user_id='user_id', app_id='app_id', compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
268377

269378
# Model Predict
270-
model_prediction = model.predict_by_url(image_url, compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
379+
model_prediction = model.f(text1= "test")
271380
```
272381

273382
#### unary-stream predict call
274383

275384
```python
276385
from clarifai.client.model import Model
277-
model = Model("url") # Example URL: https://clarifai.com/meta/Llama-3/models/llama-3_2-3b-instruct
386+
model = Model("url", compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
278387
or
279-
model = Model(model_id='model_id', user_id='user_id', app_id='app_id')
280-
stream_response = model.generate_by_url('url', compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
281-
list_stream_response = [response for response in stream_response]
388+
model = Model(model_id='model_id', user_id='user_id', app_id='app_id', compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
389+
390+
res = model.g('test')
391+
for i, r in enumerate(res):
392+
print(r)
282393
```
283394

284395

285396
#### stream-stream predict call
286397

287398
```python
288399
from clarifai.client.model import Model
289-
model = Model("url") # Example URL: https://clarifai.com/meta/Llama-3/models/llama-3_2-3b-instruct
400+
model = Model("url", , compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
290401
or
291-
model = Model(model_id='model_id', user_id='user_id', app_id='app_id')
292-
stream_response = model.stream_by_url(iter(['url']), compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
293-
list_stream_response = [response for response in stream_response]
402+
model = Model(model_id='model_id', user_id='user_id', app_id='app_id', , compute_cluster_id = "compute_cluster_id", nodepool_id= "nodepool_id")
403+
404+
res = model.s(iter(['test']))
405+
for i, r in enumerate(res):
406+
print(r)
294407
```

0 commit comments

Comments
 (0)