Skip to content

Commit

Permalink
feat: support seeding model from Huggingface repo
Browse files Browse the repository at this point in the history
  • Loading branch information
rickzx committed Aug 13, 2024
1 parent 5b2f901 commit 0e529a2
Show file tree
Hide file tree
Showing 10 changed files with 1,681 additions and 856 deletions.
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
2 changes: 2 additions & 0 deletions apis/resources/v1alpha1/bentorequest_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ type BentoRequestSpec struct {

// +kubebuilder:validation:Optional
DownloaderContainerEnvFrom []corev1.EnvFromSource `json:"downloaderContainerEnvFrom,omitempty"`
// +kubebuilder:validation:Optional
DownloaderContainerEnv []corev1.EnvVar `json:"downloaderContainerEnv,omitempty"`
}

// BentoRequestStatus defines the observed state of BentoRequest
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,458 changes: 750 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
59 changes: 46 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 @@ -1746,6 +1747,16 @@ func (r *BentoRequestReconciler) generateModelSeederPodTemplateSpec(ctx context.
}
}

hf_token := ""

Check failure on line 1750 in controllers/resources/bentorequest_controller.go

View workflow job for this annotation

GitHub Actions / golint

ST1003: should not use underscores in Go names; var hf_token should be hfToken (stylecheck)
if envs := opt.BentoRequest.Spec.DownloaderContainerEnv; envs != nil {
for _, env := range envs {
if env.Name == "HF_TOKEN" {
hf_token = env.Value
break
}
}
}

modelDirPath := "/juicefs-workspace"
var modelSeedCommandOutput bytes.Buffer
err = template.Must(template.New("script").Parse(`
Expand All @@ -1756,32 +1767,54 @@ if [ -f "{{.ModelDirPath}}/.exists" ]; then
exit 0
fi
if [ -n "{{.HfToken}}" ]; then
echo "HF_TOKEN is set, using HF_TOKEN to download model..."
export HF_TOKEN="{{.HfToken}}"
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
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
echo "Moving model to {{.ModelDirPath}}..."
mv /tmp/model/* {{.ModelDirPath}}
rm -rf /tmp/model
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
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
echo "Removing model tar file..."
rm /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,
"HfToken": hf_token,

Check failure on line 1817 in controllers/resources/bentorequest_controller.go

View workflow job for this annotation

GitHub Actions / golint

File is not `gofmt`-ed with `-s` (gofmt)
})
if err != nil {
err = errors.Wrap(err, "failed to generate download command")
Expand Down
Loading

0 comments on commit 0e529a2

Please sign in to comment.