Skip to content
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

Dockerize runtime #59

Merged
merged 10 commits into from
Jun 26, 2024
Merged

Dockerize runtime #59

merged 10 commits into from
Jun 26, 2024

Conversation

alex-jw-brooks
Copy link
Collaborator

@alex-jw-brooks alex-jw-brooks commented Jun 24, 2024

This pull request:

  • Adds a docker file for a caikit computer vision runtime (based on caikit nlp)
  • Adds definitions for text to image task
  • Adds a stub module for SDXL

@alex-jw-brooks alex-jw-brooks force-pushed the dockerize_runtime branch 4 times, most recently from 8ee351d to 147c94a Compare June 24, 2024 13:48
Add SDXL stub

Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Copy link
Contributor

@gabe-l-hart gabe-l-hart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of thoughts/comments. Depending on the goal of this PR, I think we should at least change the name of the SDXLStub to be TTIStub or something similar

COPY tox.ini .
COPY caikit_computer_vision caikit_computer_vision
# .git is required for setuptools-scm get the version
RUN --mount=source=.git,target=.git,type=bind \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is just for wheel building, but do we need tests in there too?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! I think yes, but I would like to not block this PR / the SDXL PR on it if it's alright with you, since I'm about to be OOO for a while, and I would prefer to give people an image built using stuff off of main if possible 😄

@@ -0,0 +1,51 @@
FROM registry.access.redhat.com/ubi9/ubi-minimal:latest as base
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: It would be nice to have a top-level comment in this Dockerfile. It looks like it's aimed at running the runtime and not for testing/dev, right?

Copy link
Collaborator Author

@alex-jw-brooks alex-jw-brooks Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! It's just adding a Dockerfile for building a runtime that software can test with 😄 it's probably a good idea to actually build a release wheel + test out with a container built from this though!

Dockerfile Outdated

RUN microdnf update -y && \
microdnf install -y \
python3-devel gcc git python-pip && \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is for runtime execution, I think we should try to avoid having all of these dev-centric packages in base (as opposed to build). The only exception would be if we are using pytorch.compile that requires the gcc executables at runtime.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, do you know which version of python 3 this gets you? I don't off the top of my head. If I'm not mistaken, the use of virtualenv below will still use the system python (as opposed to installing a specific version like you would with conda), right? Just trying to look for sources of bloat/redundancy.

Copy link
Collaborator Author

@alex-jw-brooks alex-jw-brooks Jun 25, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good questions - I just checked the build container, it looks like 3.9.18. I admittedly pretty much stole this Dockerfile from caikit nlp and did not optimize it at all - the virtual env stuff, and also stages are from that.

We do not pyTorch.compile anything though - I think putting the stuff that isn't python into build sounds good

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I have temporary disabled (kind of) the things that need gcc and git, so I'm just going to remove them for now - in the future, I'll reenable it in the build stage.

As far as the python venv / system python, I checked that also! Inside of the virtual environment in the container:

lrwxrwxrwx 1 root root   15 Jun 25 20:05 python -> /usr/bin/python
lrwxrwxrwx 1 root root    6 Jun 25 20:05 python3 -> python
lrwxrwxrwx 1 root root    6 Jun 25 20:05 python3.9 -> python

So yes, it looks like it is pointing at the system version, which in this base image is 3.9


FROM base as deploy

RUN python -m venv --upgrade-deps /opt/caikit/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a virtualenv is interesting here. On the one hand, it's a nice isolation mechanism, but on the other hand it will also create some duplication with the base python runtime.

@@ -18,3 +18,4 @@
from .image_classification import *
from .image_segmentation import *
from .object_detection import *
from .text_to_image import *
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ooh, nice! I have a few things for this that might be worth contributing

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do it!!



@dataobject(package="caikit_data_model.caikit_computer_vision")
class TextToImageResult(DataObjectBase):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I found with my purpose-built text-to-image module was that it was helpful to bind the input text to the image in the output object. I ended up calling it a CaptionedImage and making it inherit from Image:

@dataobject
class CaptionedImage(Image):
    """A Captioned image has a caption as well as the image itself"""
    caption: Optional[str]

    # TODO: Use type hints here once caikit supports them
    # https://github.com/caikit/caikit/issues/608
    # def __init__(self, *args, caption: Optional[str] = None, **kwargs):
    def __init__(self, *args, caption = None, **kwargs):
        """Explicitly delegate to Image's initializer so that dataobject does
        not auto-create an __init__
        """
        super().__init__(*args, **kwargs)
        self.caption = caption

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this more than the current output type! Currently things are written the way they are because of the way software expects image to be formatted, which is basically wrapping encoded bytes of a compressed image. I greatly prefer this also though! For now, I would like to continue with this output format if you're alright with it, since this is what they have been testing with also, but I think it would be a good idea to add this to caikit and update the result to use this in the future.

I suspect this is the route that they will want to go too, since they had already started talking about returning a JSON object with stuff + image instead of just the encoded image 🤞

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'm a little confused on how this structure accomplishes the goal of having the output be just encoded bytes. I would expect that you would still need to call some function on the output field to get those bytes encoded, right? If this is returned from a task in caikit.runtime, it would return as a json blob or serialized proto with output and producer_id fields unless there's something in the core Image that would provide custom serialization?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! That is in the data model for image, the image data model holds an export format, which by default is png. when you get the attribute of image data on the image backend, it makes a BytesIO object and exports it with PIL here!

@@ -61,3 +62,14 @@ class ImageSegmentationTask(TaskBase):
Note that at the moment, this task encapsulates all segmentation types,
I.e., instance, object, semantic, etc...
"""


@task(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks very similar to my personal definition of this (with the change of CaptionedImage, see below)

@task(
    unary_parameters={"text": dm.TextDocument},
    unary_output_type=dm.CaptionedImage,
)
class TextToImageTask(TaskBase):
    """Task of generating an image from text"""

caikit_computer_vision/modules/text_to_image/sdxl_stub.py Outdated Show resolved Hide resolved
with saver:
saver.update_config({"model_name": self.model_name})

def run(self, inputs: str, height: int, width: int) -> TextToImageResult:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, ok, so this seems to be just a stub and not actually have anything to do with sdxl, right? I think we should change the name unless you plan to update it to actually support running sdxl. As written, I think this is more of a unit test stub, right?

Copy link
Collaborator Author

@alex-jw-brooks alex-jw-brooks Jun 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh yes, sorry! This is a little disorganized - it is just a stub + Dockerfile in this one. I am still splitting some stuff apart a bit, but I wrote this and pushed an image with it so that software could test wiring more easily.

There is an SDXL block too, but it's in a separate PR that is on top of this one that I am rebasing at the moment (here)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that makes sense. I still think this should be named tti_stub since we eventually imagine multiple modules for tti and this is not sdxl specific

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! Renamed

Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
Copy link
Contributor

@gabe-l-hart gabe-l-hart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ship it (once you've got the rename of CaptionedImage done 😉)

Signed-off-by: Alex-Brooks <Alex.Brooks@ibm.com>
@alex-jw-brooks alex-jw-brooks merged commit a329759 into main Jun 26, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants