Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- **Store models in a central location.** Never again will you have to hunt for the right model file on S3 and figure out the right code to load it. Cog models are in one place with a content-addressable ID.
- **Package everything that a model needs to run.** Code, weights, pre/post-processing, data types, Python dependencies, system dependencies, CUDA version, etc etc. No more dependency hell.
- **Let anyone ship models to production.** Cog packages can be deployed to anywhere that runs Docker images, without having to understand Dockerfiles, CUDA, and all that horrible stuff.
- **Let anyone ship models to production.** Cog models can be deployed to anywhere that runs Docker images, without having to understand Dockerfiles, CUDA, and all that horrible stuff.


## How does it work?
Expand Down Expand Up @@ -48,9 +48,9 @@ $ cog build

This has:

- **Created a package**, a ZIP file containing your code + weights + environment definition, and assigned it a content-addressable SHA256 ID.
- **Pushed this package up to a central registry** so it never gets lost and can be run by anyone.
- **Built two Docker images** (one for CPU and one for GPU) that contains the package in a reproducible environment, with the correct versions of Python, your dependencies, CUDA, etc.
- **Created a model**, a ZIP file containing your code + weights + environment definition, and assigned it a content-addressable SHA256 ID.
- **Pushed this model up to a central registry** so it never gets lost and can be run by anyone.
- **Built two Docker images** (one for CPU and one for GPU) that contains the model in a reproducible environment, with the correct versions of Python, your dependencies, CUDA, etc.

## Install

Expand All @@ -71,22 +71,22 @@ Then, hook up Cog to the server (replace "localhost" with your server's IP if it

cog remote set http://localhost:8080

Next, let's build a package. We have [some models you can play around with](https://github.com/replicate/cog-examples). Clone that repository (you'll need git-lfs) and then build a package out of a model:
Next, let's build a model. We have [some models you can play around with](https://github.com/replicate/cog-examples). Clone that repository (you'll need git-lfs) and then build a model out of a model:

cd example-models/inst-colorization/
cog build

This will take a few minutes. In the meantime take a look at `cog.yaml` and `infer.py` to see how it works.

When that has finished, you can run inferences on the built model from any machine that is pointed at the server. Replace the ID with your package's ID, and the file with an image on your disk you want to colorize:
When that has finished, you can run inferences on the built model from any machine that is pointed at the server. Replace the ID with your model's ID, and the file with an image on your disk you want to colorize:

cog infer b31f9f72d8f14f0eacc5452e85b05c957b9a8ed9 -i @hotdog.jpg

You can see more details about the package:
You can see more details about the model:

cog show b31f9f72d8f14f0eacc5452e85b05c957b9a8ed9

You can also list the packages for this repo:
You can also list the models for this repo:

cog list

Expand Down
16 changes: 8 additions & 8 deletions end-to-end-test/end_to_end_test/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,32 +96,32 @@ def run(self, text, path):
assert out.decode().startswith("Successfully built "), (
out.decode() + " doesn't start with 'Successfully built'"
)
package_id = out.decode().strip().split("Successfully built ")[1]
model_id = out.decode().strip().split("Successfully built ")[1]

out, _ = subprocess.Popen(
["cog", "-r", repo, "show", package_id], stdout=subprocess.PIPE
["cog", "-r", repo, "show", model_id], stdout=subprocess.PIPE
).communicate()
lines = out.decode().splitlines()
assert lines[0] == f"ID: {package_id}"
assert lines[0] == f"ID: {model_id}"
assert lines[1] == f"Repo: {user}/{repo_name}"

# show without -r
out, _ = subprocess.Popen(
["cog", "show", package_id],
["cog", "show", model_id],
stdout=subprocess.PIPE,
cwd=project_dir,
).communicate()
lines = out.decode().splitlines()
assert lines[0] == f"ID: {package_id}"
assert lines[0] == f"ID: {model_id}"
assert lines[1] == f"Repo: {user}/{repo_name}"

out, _ = subprocess.Popen(["cog", "-r", repo, "ls"], stdout=subprocess.PIPE).communicate()
lines = out.decode().splitlines()
assert lines[1].startswith(f"{package_id} ")
assert lines[1].startswith(f"{model_id} ")

download_dir = tmpdir_factory.mktemp("download") / "my-dir"
subprocess.Popen(
["cog", "-r", repo, "download", "--output-dir", download_dir, package_id],
["cog", "-r", repo, "download", "--output-dir", download_dir, model_id],
stdout=subprocess.PIPE,
).communicate()
paths = sorted(glob(str(download_dir / "*.*")))
Expand All @@ -146,7 +146,7 @@ def run(self, text, path):
"text=baz",
"-i",
f"path=@{input_path}",
package_id,
model_id,
],
stdout=subprocess.PIPE,
).communicate()
Expand Down
28 changes: 14 additions & 14 deletions pkg/cli/benchmark.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ type BenchmarkResults struct {
func newBenchmarkCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "benchmark",
Short: "Measure setup and runtime of package, using the first example from config",
RunE: benchmarkPackage,
Short: "Measure setup and runtime of model, using the first example from config",
RunE: benchmarkModel,
Args: cobra.ExactArgs(1),
}

Expand All @@ -39,7 +39,7 @@ func newBenchmarkCommand() *cobra.Command {
return cmd
}

func benchmarkPackage(cmd *cobra.Command, args []string) error {
func benchmarkModel(cmd *cobra.Command, args []string) error {
repo, err := getRepo()
if err != nil {
return err
Expand All @@ -49,26 +49,26 @@ func benchmarkPackage(cmd *cobra.Command, args []string) error {
cli := client.NewClient()
console.Info("Starting benchmark of %s:%s", repo, id)

pkg, err := cli.GetPackage(repo, id)
mod, err := cli.GetModel(repo, id)
if err != nil {
return err
}
if len(pkg.Config.Examples) == 0 {
return fmt.Errorf("Package has no examples, cannot run benchmark")
if len(mod.Config.Examples) == 0 {
return fmt.Errorf("Model has no examples, cannot run benchmark")
}

pkgDir, err := os.MkdirTemp("/tmp", "benchmark")
modelDir, err := os.MkdirTemp("/tmp", "benchmark")
if err != nil {
return err
}
defer os.RemoveAll(pkgDir)
if err := cli.DownloadPackage(repo, id, pkgDir); err != nil {
defer os.RemoveAll(modelDir)
if err := cli.DownloadModel(repo, id, modelDir); err != nil {
return err
}
results := new(BenchmarkResults)
for i := 0; i < benchmarkSetups; i++ {
console.Info("Running setup iteration %d", i+1)
if err := runBenchmarkInference(pkg, pkgDir, results, benchmarkRuns); err != nil {
if err := runBenchmarkInference(mod, modelDir, results, benchmarkRuns); err != nil {
return err
}
}
Expand All @@ -89,18 +89,18 @@ func benchmarkPackage(cmd *cobra.Command, args []string) error {
return nil
}

func runBenchmarkInference(pkg *model.Model, pkgDir string, results *BenchmarkResults, runIterations int) error {
func runBenchmarkInference(mod *model.Model, modelDir string, results *BenchmarkResults, runIterations int) error {
servingPlatform, err := serving.NewLocalDockerPlatform()
if err != nil {
return err
}

example := pkg.Config.Examples[0]
input := serving.NewExampleWithBaseDir(example.Input, pkgDir)
example := mod.Config.Examples[0]
input := serving.NewExampleWithBaseDir(example.Input, modelDir)

logWriter := logger.NewConsoleLogger()
bootStart := time.Now()
deployment, err := servingPlatform.Deploy(pkg, model.TargetDockerCPU, logWriter)
deployment, err := servingPlatform.Deploy(mod, model.TargetDockerCPU, logWriter)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ import (
func newBuildCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "build",
Short: "Build Cog package",
RunE: buildPackage,
Short: "Build Cog model",
RunE: buildModel,
Args: cobra.NoArgs,
}
addRepoFlag(cmd)

return cmd
}

func buildPackage(cmd *cobra.Command, args []string) error {
func buildModel(cmd *cobra.Command, args []string) error {
repo, err := getRepo()
if err != nil {
return err
Expand All @@ -43,7 +43,7 @@ func buildPackage(cmd *cobra.Command, args []string) error {
console.Info("Uploading %s to %s", projectDir, repo)

cli := client.NewClient()
mod, err := cli.UploadPackage(repo, projectDir)
mod, err := cli.UploadModel(repo, projectDir)
if err != nil {
return err
}
Expand Down
10 changes: 5 additions & 5 deletions pkg/cli/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,25 @@ import (
func newDeleteCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "delete",
Short: "Delete a package",
RunE: deletePackage,
Short: "Delete a model",
RunE: deleteModel,
Args: cobra.MinimumNArgs(1),
Aliases: []string{"rm"},
}
return cmd
}

func deletePackage(cmd *cobra.Command, args []string) error {
func deleteModel(cmd *cobra.Command, args []string) error {
repo, err := getRepo()
if err != nil {
return err
}
cli := client.NewClient()
for _, id := range args {
if err := cli.DeletePackage(repo, id); err != nil {
if err := cli.DeleteModel(repo, id); err != nil {
return err
}
fmt.Printf("Deleted package %s:%s\n", repo, id)
fmt.Printf("Deleted model %s:%s\n", repo, id)
}
return nil
}
10 changes: 5 additions & 5 deletions pkg/cli/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ var downloadOutputDir string
func newDownloadCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "download <id>",
Short: "Download a model package",
RunE: downloadPackage,
Short: "Download a model",
RunE: downloadModel,
Args: cobra.ExactArgs(1),
}
addRepoFlag(cmd)
Expand All @@ -28,7 +28,7 @@ func newDownloadCommand() *cobra.Command {
return cmd
}

func downloadPackage(cmd *cobra.Command, args []string) (err error) {
func downloadModel(cmd *cobra.Command, args []string) (err error) {
repo, err := getRepo()
if err != nil {
return err
Expand Down Expand Up @@ -58,10 +58,10 @@ func downloadPackage(cmd *cobra.Command, args []string) (err error) {
}

cli := client.NewClient()
if err := cli.DownloadPackage(repo, id, downloadOutputDir); err != nil {
if err := cli.DownloadModel(repo, id, downloadOutputDir); err != nil {
return err
}

fmt.Printf("Downloaded package %s into %s\n", id, downloadOutputDir)
fmt.Printf("Downloaded model %s into %s\n", id, downloadOutputDir)
return nil
}
8 changes: 4 additions & 4 deletions pkg/cli/infer.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ func cmdInfer(cmd *cobra.Command, args []string) error {
return err
}

packageId := args[0]
modelId := args[0]

client := client.NewClient()
fmt.Println("Loading package", packageId)
pkg, err := client.GetPackage(repo, packageId)
fmt.Println("Loading package", modelId)
mod, err := client.GetModel(repo, modelId)
if err != nil {
return err
}
Expand All @@ -63,7 +63,7 @@ func cmdInfer(cmd *cobra.Command, args []string) error {
}
logWriter := logger.NewConsoleLogger()
// TODO(andreas): GPU inference
deployment, err := servingPlatform.Deploy(pkg, model.TargetDockerCPU, logWriter)
deployment, err := servingPlatform.Deploy(mod, model.TargetDockerCPU, logWriter)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
func newListCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "list",
Short: "List Cog packages",
RunE: listPackages,
Short: "List Cog models",
RunE: listModels,
Args: cobra.NoArgs,
Aliases: []string{"ls"},
}
Expand All @@ -25,14 +25,14 @@ func newListCommand() *cobra.Command {
return cmd
}

func listPackages(cmd *cobra.Command, args []string) error {
func listModels(cmd *cobra.Command, args []string) error {
repo, err := getRepo()
if err != nil {
return err
}

cli := client.NewClient()
models, err := cli.ListPackages(repo)
models, err := cli.ListModels(repo)
if err != nil {
return err
}
Expand Down
8 changes: 4 additions & 4 deletions pkg/cli/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
func newShowCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "show <id>",
Short: "Inspect a Cog package",
RunE: showPackage,
Short: "Inspect a Cog model",
RunE: showModel,
Args: cobra.ExactArgs(1),
SuggestFor: []string{"inspect"},
}
Expand All @@ -24,7 +24,7 @@ func newShowCommand() *cobra.Command {
return cmd
}

func showPackage(cmd *cobra.Command, args []string) error {
func showModel(cmd *cobra.Command, args []string) error {
repo, err := getRepo()
if err != nil {
return err
Expand All @@ -33,7 +33,7 @@ func showPackage(cmd *cobra.Command, args []string) error {
id := args[0]

cli := client.NewClient()
mod, err := cli.GetPackage(repo, id)
mod, err := cli.GetModel(repo, id)
if err != nil {
return err
}
Expand Down
5 changes: 2 additions & 3 deletions pkg/client/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
"github.com/replicate/cog/pkg/model"
)

// The URL says "package" but the code says "Model", sob
func (c *Client) DeletePackage(repo *model.Repo, id string) error {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/packages/%s", repo.Host, repo.User, repo.Name, id)
func (c *Client) DeleteModel(repo *model.Repo, id string) error {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/models/%s", repo.Host, repo.User, repo.Name, id)
req, err := http.NewRequest(http.MethodDelete, url, nil)
if err != nil {
return err
Expand Down
8 changes: 4 additions & 4 deletions pkg/client/download.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/replicate/cog/pkg/model"
)

func (c *Client) DownloadPackage(repo *model.Repo, id string, outputDir string) error {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/packages/%s.zip", repo.Host, repo.User, repo.Name, id)
func (c *Client) DownloadModel(repo *model.Repo, id string, outputDir string) error {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/models/%s.zip", repo.Host, repo.User, repo.Name, id)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return fmt.Errorf("Failed to create HTTP request: %w", err)
Expand All @@ -24,10 +24,10 @@ func (c *Client) DownloadPackage(repo *model.Repo, id string, outputDir string)
}

if resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Package ID doesn't exist: %s", id)
return fmt.Errorf("Model ID doesn't exist: %s", id)
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Package zip endpoint returned status %d", resp.StatusCode)
return fmt.Errorf("Model zip endpoint returned status %d", resp.StatusCode)
}

bar := progressbar.DefaultBytes(
Expand Down
5 changes: 2 additions & 3 deletions pkg/client/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ import (
"github.com/replicate/cog/pkg/model"
)

// The URL says "package" but the code says "Model", sob
func (c *Client) GetPackage(repo *model.Repo, id string) (*model.Model, error) {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/packages/%s", repo.Host, repo.User, repo.Name, id)
func (c *Client) GetModel(repo *model.Repo, id string) (*model.Model, error) {
url := fmt.Sprintf("http://%s/v1/repos/%s/%s/models/%s", repo.Host, repo.User, repo.Name, id)
resp, err := http.Get(url)
if err != nil {
return nil, err
Expand Down
Loading