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

feat: support seeding model from Huggingface repo #81

Merged
merged 2 commits into from
Aug 14, 2024
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
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ ENVTEST ?= $(LOCALBIN)/setup-envtest

## Tool Versions
KUSTOMIZE_VERSION ?= v3.8.7
CONTROLLER_TOOLS_VERSION ?= v0.9.2
CONTROLLER_TOOLS_VERSION ?= v0.14.0

KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"
.PHONY: kustomize
Expand Down
8 changes: 8 additions & 0 deletions bento-downloader/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ FROM ubuntu:22.04

RUN apt-get update
RUN apt-get install -y curl jq unzip xz-utils file
RUN apt-get update && apt-get install -y \
python3 \
python3-pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN pip3 install --upgrade pip
RUN pip3 install -U "huggingface_hub[cli]"
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" \
&& unzip awscliv2.zip \
&& ./aws/install \
Expand Down
4 changes: 2 additions & 2 deletions bento-downloader/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
IMAGE := quay.io/bentoml/bento-downloader:0.0.1
IMAGE := quay.io/bentoml/bento-downloader:0.0.4

build:
docker build -t ${IMAGE} .
docker buildx build --platform linux/amd64 -t ${IMAGE} .
docker push ${IMAGE}
1,347 changes: 639 additions & 708 deletions config/crd/bases/resources.yatai.ai_bentorequests.yaml

Large diffs are not rendered by default.

131 changes: 131 additions & 0 deletions config/crd/bases/resources.yatai.ai_bentos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.14.0
name: bentos.resources.yatai.ai
spec:
group: resources.yatai.ai
names:
kind: Bento
listKind: BentoList
plural: bentos
singular: bento
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Tag
jsonPath: .spec.tag
name: Tag
type: string
- description: Image
jsonPath: .spec.image
name: Image
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: Bento is the Schema for the bentoes API
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: BentoSpec defines the desired state of Bento
properties:
context:
properties:
bentomlVersion:
type: string
type: object
image:
type: string
imagePullSecrets:
items:
description: |-
LocalObjectReference contains enough information to let you locate the
referenced object inside the same namespace.
properties:
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
type: object
x-kubernetes-map-type: atomic
type: array
models:
items:
properties:
downloadUrl:
type: string
size:
anyOf:
- type: integer
- type: string
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
tag:
type: string
required:
- tag
type: object
type: array
runners:
items:
properties:
modelTags:
items:
type: string
type: array
name:
type: string
runnableType:
type: string
required:
- name
type: object
type: array
serviceName:
type: string
tag:
type: string
required:
- image
- tag
type: object
status:
description: BentoStatus defines the observed state of Bento
properties:
ready:
description: |-
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
Important: Run "make" to regenerate code after modifying this file
type: boolean
required:
- ready
type: object
type: object
served: true
storage: true
subresources:
status: {}
1 change: 0 additions & 1 deletion config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: manager-role
rules:
- apiGroups:
Expand Down
48 changes: 35 additions & 13 deletions controllers/resources/bentorequest_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1701,6 +1701,7 @@ func (r *BentoRequestReconciler) generateModelSeederPodTemplateSpec(ctx context.

model := opt.Model

modelTag := model.Tag
modelDownloadURL := model.DownloadURL
modelDownloadHeader := ""
if modelDownloadURL == "" {
Expand Down Expand Up @@ -1758,30 +1759,51 @@ fi

mkdir -p {{.ModelDirPath}}
url="{{.ModelDownloadURL}}"
echo "Downloading model {{.ModelRepositoryName}}:{{.ModelVersion}} to /tmp/downloaded.tar..."
if [[ ${url} == s3://* ]]; then
echo "Downloading from s3..."
aws s3 cp ${url} /tmp/downloaded.tar
elif [[ ${url} == gs://* ]]; then
echo "Downloading from GCS..."
gsutil cp ${url} /tmp/downloaded.tar

rickzx marked this conversation as resolved.
Show resolved Hide resolved
cleanup() {
echo "Cleaning up..."
rm -rf /tmp/model
rm -f /tmp/downloaded.tar
}
rickzx marked this conversation as resolved.
Show resolved Hide resolved

trap cleanup EXIT

if [[ ${url} == hf://* ]]; then
mkdir -p /tmp/model
hf_url="${url:5}"
model_id=$(echo "${hf_url}" | cut -d '@' -f 1)
endpoint=$(echo "${hf_url}" | cut -d '@' -f 2)
revision=$(echo "{{.ModelTag}}" | cut -d ':' -f 2)
echo "Downloading model ${model_id} (endpoint=${endpoint}, revision=${revision}) from Huggingface..."
export HF_ENDPOINT=${endpoint}
huggingface-cli download ${model_id} --revision ${revision} --local-dir /tmp/model
yetone marked this conversation as resolved.
Show resolved Hide resolved
echo "Moving model to {{.ModelDirPath}}..."
mv /tmp/model/* {{.ModelDirPath}}
else
curl --fail -L -H "{{.ModelDownloadHeader}}" ${url} --output /tmp/downloaded.tar --progress-bar
echo "Downloading model {{.ModelRepositoryName}}:{{.ModelVersion}} to /tmp/downloaded.tar..."
if [[ ${url} == s3://* ]]; then
echo "Downloading from s3..."
aws s3 cp ${url} /tmp/downloaded.tar
Copy link
Member

Choose a reason for hiding this comment

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

‌‌‌‌‌‌‌Is this acceptable? This way, there's no need to clean up /tmp/downloaded.tar, it reduces two disk I/O operations, and it decreases the writing to the container's writable layer, thus reducing the usage of ephemeral storage.

aws s3 cp {url} - | tar -xv -C {{.ModelDirPath}}

elif [[ ${url} == gs://* ]]; then
echo "Downloading from GCS..."
gsutil cp ${url} /tmp/downloaded.tar
else
curl --fail -L -H "{{.ModelDownloadHeader}}" ${url} --output /tmp/downloaded.tar --progress-bar
fi
cd {{.ModelDirPath}}
echo "Extracting model tar file..."
tar -xvf /tmp/downloaded.tar
fi
cd {{.ModelDirPath}}
echo "Extracting model tar file..."
tar -xvf /tmp/downloaded.tar
echo "Creating {{.ModelDirPath}}/.exists file..."
touch {{.ModelDirPath}}/.exists
echo "Removing model tar file..."
rm /tmp/downloaded.tar
echo "Done"
`)).Execute(&modelSeedCommandOutput, map[string]interface{}{
"ModelDirPath": modelDirPath,
"ModelDownloadURL": modelDownloadURL,
"ModelDownloadHeader": modelDownloadHeader,
"ModelRepositoryName": modelRepositoryName,
"ModelVersion": modelVersion,
"ModelTag": modelTag,
})
if err != nil {
err = errors.Wrap(err, "failed to generate download command")
Expand Down
Loading
Loading