-
Notifications
You must be signed in to change notification settings - Fork 694
Move examples from cog-examples to cog #3055
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
9d15254
feat: add examples
anish-sahoo c846fec
format: go and python
anish-sahoo ffe15ec
fix: lint and format refactoring
anish-sahoo f5515f6
fix: code review and update cargo deny
anish-sahoo a190ffa
feat: add secret support to coglet
anish-sahoo 0753138
fix: review fixes for examples and test-harness
anish-sahoo 2112b99
feat: move resnet to experimental
anish-sahoo 16c390c
refactor: split out Secret support; address example review comments
anish-sahoo ac03777
refactor(test-harness): base_dir-first model resolution
anish-sahoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Blur | ||
|
|
||
| This model applies box blur to an input image. | ||
|
|
||
| ## Usage | ||
|
|
||
| First, make sure you've got the [latest version of Cog](https://github.com/replicate/cog#install) installed. | ||
|
|
||
| Run predictions on the model: | ||
|
|
||
| ```sh | ||
| cog predict -i image=@examples/kodim24.png -i blur=4 | ||
|
|
||
| cog predict -i image=@examples/kodim24.png -i blur=6 | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| build: | ||
| python_version: "3.12" | ||
| python_requirements: requirements.txt | ||
| run: "run.py:Runner" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| pillow==12.1.1 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| import tempfile | ||
|
|
||
| from PIL import Image, ImageFilter | ||
|
|
||
| from cog import BaseRunner, Input, Path | ||
|
|
||
|
|
||
| class Runner(BaseRunner): | ||
| def run( | ||
| self, | ||
| image: Path = Input(description="Input image"), | ||
| blur: float = Input(description="Blur radius", default=5), | ||
| ) -> Path: | ||
| if blur == 0: | ||
| return image | ||
| im = Image.open(str(image)) | ||
| im = im.filter(ImageFilter.BoxBlur(blur)) | ||
| out_path = Path(tempfile.mkdtemp()) / "out.png" | ||
| im.save(str(out_path)) | ||
| return out_path |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Canary | ||
|
|
||
| This simple model takes a string as input and returns a streaming string output. | ||
|
|
||
| ## Usage | ||
|
|
||
| First, make sure you've got the [latest version of Cog](https://github.com/replicate/cog#install) installed. | ||
|
|
||
| Run predictions on the model: | ||
|
|
||
| ```sh | ||
| cog predict -i text=Athena | ||
|
|
||
| cog predict -i text=Zeus | ||
| ``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| build: | ||
| python_version: "3.12" | ||
| run: "run.py:Runner" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| from cog import BaseRunner, ConcatenateIterator, Input | ||
|
|
||
|
|
||
| class Runner(BaseRunner): | ||
| def run( | ||
| self, text: str = Input(description="Text to prefix with 'hello there, '") | ||
| ) -> ConcatenateIterator[str]: | ||
| yield "hello " | ||
| yield "there, " | ||
| yield text |
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| # examples/experimental/resnet-managed-weights | ||
|
|
||
| ResNet50 image classifier (microsoft/resnet-50 from HuggingFace) packaged | ||
| with v1 managed weights. Takes an image, returns top-3 ImageNet classes. | ||
|
|
||
| Use this as a starting point for packaging a real model with managed weights. | ||
|
|
||
| ## What are managed weights? | ||
|
|
||
| Managed weights separate your model weights from your model image. Instead of | ||
| baking multi-GB weight files into the Docker image (slow builds, huge layers), | ||
| cog packs them into dedicated OCI layers that get mounted at runtime. | ||
|
|
||
| The key idea: your `run.py` reads weights from a path like | ||
| `/src/weights/resnet50`, but those files don't live inside the Docker image -- | ||
| they arrive separately and get overlaid at that path when the container starts. | ||
|
|
||
| ## File layout | ||
|
|
||
| ``` | ||
| examples/experimental/resnet-managed-weights/ | ||
| ├── cog.yaml # model config -- declares weights, build settings | ||
| ├── run.py # runner -- loads weights from target path | ||
| ├── requirements.txt # python deps | ||
| ├── weights.lock # generated by `cog weights import` -- don't hand-edit | ||
| ├── .dockerignore # keeps local weight dirs out of the Docker build context | ||
| ├── .gitignore # keeps local weight dirs and .cog/ out of git | ||
| ├── hotdog.png # test image | ||
| └── cat.png # test image | ||
| ``` | ||
|
|
||
| Weight files themselves don't live in the project directory. `cog weights import` | ||
| downloads them into a content-addressed store at `~/.cache/cog/weights/` (override | ||
| with `$COG_CACHE_DIR`). When you run `cog run`, cog assembles a temporary | ||
| directory under `.cog/mounts/` using hardlinks from the store and bind-mounts it | ||
| into the container at the `target` path. The mount dir is cleaned up when the | ||
| container stops. | ||
|
|
||
| ## How `cog.yaml` works | ||
|
|
||
| ```yaml | ||
| weights: | ||
| - name: resnet50 | ||
| source: | ||
| uri: hf://microsoft/resnet-50 # where to fetch from | ||
| exclude: # files to skip | ||
| - "pytorch_model.bin" | ||
| - "flax_model.msgpack" | ||
| - "tf_model.h5" | ||
| - "README.md" | ||
| - ".gitattributes" | ||
| target: /src/weights/resnet50 # where files appear in the container | ||
| ``` | ||
|
|
||
| **`name`** -- an identifier for this weight set. Used in lockfile entries and | ||
| OCI tags. Pick something short and descriptive. | ||
|
|
||
| **`source.uri`** -- where the weights come from. Two formats: | ||
|
|
||
| - `hf://<org>/<repo>` -- pulls from HuggingFace Hub | ||
| - A local directory path (e.g. `weights/`) -- uses files already on disk | ||
|
|
||
| **`source.exclude`** -- glob patterns for files to skip. Most HF repos ship | ||
| weights in multiple formats (PyTorch, TF, Flax, ONNX). Exclude the ones you | ||
| don't need -- it'll save gigabytes. | ||
|
|
||
| **`target`** -- the absolute path where weight files land inside the container. | ||
| Your `run.py` loads from this path. Must start with `/`. | ||
|
|
||
| ## Getting started | ||
|
|
||
| ### 1. Import weights | ||
|
|
||
| This downloads weight files from HuggingFace into the local cache and | ||
| generates `weights.lock`: | ||
|
|
||
| ```sh | ||
| cd examples/experimental/resnet-managed-weights | ||
| cog weights import | ||
| ``` | ||
|
|
||
| The lockfile records digests and sizes for every file. It's how cog knows | ||
| whether weights have changed on subsequent imports. Commit `weights.lock` | ||
| to version control. | ||
|
|
||
| ### 2. Run a prediction locally | ||
|
|
||
| ```sh | ||
| cog run -i image=@hotdog.png | ||
| ``` | ||
|
|
||
| Locally, cog assembles the weight files from the cache and bind-mounts them | ||
| into the container at the `target` path. You don't need to push anything to test. | ||
|
|
||
| ### 3. Build and push | ||
|
|
||
| ```sh | ||
| cog push | ||
| ``` | ||
|
|
||
| This builds the model image and pushes it as the model named by `model:` | ||
| in `cog.yaml`, alongside the weight layers as an OCI image index. The weights | ||
| and model image are separate artifacts in the registry -- the image index ties | ||
| them together. | ||
|
|
||
| ## Important: `.dockerignore` | ||
|
|
||
| The `.dockerignore` excludes `weights/` and `.cog/weights-cache/` from the | ||
| Docker build context. This matters if you're using local directory weight | ||
| sources -- without it, Docker would send the full weight directory to the | ||
| build daemon on every `cog build`. | ||
|
|
||
| ## Adapting this for your own model | ||
|
|
||
| 1. Copy this directory as a starting point | ||
| 2. Edit `cog.yaml`: | ||
| - Change `source.uri` to your HuggingFace repo (or a local path) | ||
| - Adjust `exclude` patterns for the formats you don't need | ||
| - Set `target` to wherever your code expects to find the weights | ||
| - Set `model` to your model name (required for `cog push`) | ||
| 3. Edit `run.py` to load your model from `WEIGHTS_DIR` | ||
| 4. Update `requirements.txt` with your dependencies | ||
| 5. Run `cog weights import` to fetch weights and generate the lockfile | ||
| 6. Test with `cog run` | ||
| 7. Push with `cog push` | ||
|
|
||
| ### Using local weights instead of HuggingFace | ||
|
|
||
| If you already have weights on disk (downloaded separately, trained locally, | ||
| etc.), point the source at a local directory: | ||
|
|
||
| ```yaml | ||
| weights: | ||
| - name: my-model | ||
| source: | ||
| uri: my-weights-dir/ | ||
| include: | ||
| - "*.safetensors" | ||
| - "*.json" | ||
| target: /src/weights/my-model | ||
| ``` | ||
|
|
||
| Then run `cog weights import` as usual -- it'll hash the local files and | ||
| generate the lockfile. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| # ResNet50 image classifier using v1 managed weights. | ||
| # | ||
| # Weights are pulled from HuggingFace at import time: | ||
| # cog weights import | ||
| # | ||
| # Build and push: | ||
| # cog push | ||
|
|
||
| model: resnet-managed-weights | ||
|
|
||
| build: | ||
| gpu: true | ||
| python_version: "3.13" | ||
| python_requirements: requirements.txt | ||
|
|
||
| run: "run.py:Runner" | ||
|
|
||
| weights: | ||
| - name: resnet50 | ||
| source: | ||
| uri: hf://microsoft/resnet-50 | ||
| exclude: | ||
| - "pytorch_model.bin" # legacy format, redundant with model.safetensors | ||
| - "flax_model.msgpack" # Flax/JAX weights | ||
| - "tf_model.h5" # TensorFlow weights | ||
| - "README.md" | ||
| - ".gitattributes" | ||
| target: /src/weights/resnet50 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions
3
examples/experimental/resnet-managed-weights/requirements.txt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| pillow==12.1.1 | ||
| torch==2.8.0 | ||
| transformers==4.52.3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import torch | ||
| from PIL import Image | ||
| from transformers import AutoImageProcessor, ResNetForImageClassification | ||
|
|
||
| from cog import BaseRunner, Input, Path | ||
|
|
||
| WEIGHTS_DIR = "/src/weights/resnet50" | ||
|
|
||
|
|
||
| class Runner(BaseRunner): | ||
| def setup(self) -> None: | ||
| self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | ||
| self.processor = AutoImageProcessor.from_pretrained(WEIGHTS_DIR) | ||
| self.model = ResNetForImageClassification.from_pretrained(WEIGHTS_DIR) | ||
| self.model = self.model.to(self.device) | ||
| self.model.eval() | ||
|
|
||
| def run(self, image: Path = Input(description="Image to classify")) -> dict: | ||
| img = Image.open(image).convert("RGB") | ||
| inputs = self.processor(img, return_tensors="pt").to(self.device) | ||
|
|
||
| with torch.no_grad(): | ||
| logits = self.model(**inputs).logits | ||
|
|
||
| top3 = logits[0].softmax(0).topk(3) | ||
| labels = self.model.config.id2label | ||
| return {labels[i.item()]: p.item() for p, i in zip(*top3, strict=True)} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| # The .dockerignore file excludes files from the container build process. | ||
| # | ||
| # https://docs.docker.com/engine/reference/builder/#dockerignore-file | ||
|
|
||
| # Exclude Git files | ||
| .git | ||
| .github | ||
| .gitignore | ||
|
|
||
| # Exclude Python cache files | ||
| __pycache__ | ||
| .mypy_cache | ||
| .pytest_cache | ||
| .ruff_cache | ||
|
|
||
| # Exclude Python virtual environment | ||
| .venv | ||
| venv |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| .venv | ||
| honeycomb_token.key |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| # hello-concurrency | ||
|
|
||
| This is an example Cog project that demonstrates the newly added concurrency support within | ||
| cog >= 0.14.0. | ||
|
|
||
| The key piece is the new `concurrency` field in the cog.yaml. | ||
|
|
||
| ```yaml | ||
| concurrency: | ||
| max: 4 | ||
| ``` | ||
|
|
||
| This combined with the async setup and run methods in `run.py` allows Cog to run up to | ||
| 4 concurrent predictions. If Cog reaches the max concurrency threshold it will reject subsequent | ||
| predictions with a `409 Conflict` response. | ||
|
|
||
| ### Telemetry | ||
|
|
||
| It also uses the open-telemetry package to demonstrate how to collect telemetry for your model. | ||
|
|
||
| This requires a file named `honeycomb_token.key` to be included in the image build. | ||
|
|
||
| It will then start sending events to the `cog-model` data source. You can configure this by | ||
| editing the `OTEL_SERVICE_NAME`. If you use a custom endpoint this can be configured via `OTEL_EXPORTER_OTLP_ENDPOINT`. | ||
|
|
||
| Lastly, there is a section in `run.py` that can be uncommented to run telemetry locally and print events to the console for debugging. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| # Configuration for Cog ⚙️ | ||
| # Reference: https://github.com/replicate/cog/blob/main/docs/yaml.md | ||
| build: | ||
| gpu: false | ||
| python_version: "3.12" | ||
| python_requirements: requirements.txt | ||
| run: "run.py:Runner" | ||
| concurrency: | ||
| max: 4 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| opentelemetry-api | ||
| opentelemetry-sdk | ||
| opentelemetry-exporter-otlp-proto-http |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.