Skip to content

Commit 96c5f79

Browse files
authored
Merge pull request #657 from basetenlabs/bump-version-0.7.5
Release 0.7.5
2 parents 42370b3 + 600379d commit 96c5f79

File tree

5 files changed

+59
-3
lines changed

5 files changed

+59
-3
lines changed

docs/welcome.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ description: "The simplest way to serve AI/ML models in production"
77

88
* **Write once, run anywhere:** Package and test model code, weights, and dependencies with a model server that behaves the same in development and production.
99
* **Fast developer loop:** Implement your model with fast feedback from a live reload server, and skip Docker and Kubernetes configuration with a batteries-included model serving environment.
10-
* **Support for all Python frameworks**: From `transformers` and `diffusors` to `PyTorch` and `Tensorflow` to `XGBoost` and `sklearn`, Truss supports models created with any framework, even entirely custom models.
10+
* **Support for all Python frameworks**: From `transformers` and `diffusers` to `PyTorch` and `Tensorflow` to `XGBoost` and `sklearn`, Truss supports models created with any framework, even entirely custom models.
1111

1212
See Trusses for popular models including:
1313

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "truss"
3-
version = "0.7.4"
3+
version = "0.7.5"
44
description = "A seamless bridge from model development to model delivery"
55
license = "MIT"
66
readme = "README.md"

truss/contexts/image_builder/cache_warmer.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,36 @@ def _download_from_url_using_b10cp(
3232
)
3333

3434

35+
def split_gs_path(gs_path):
36+
# Remove the 'gs://' prefix
37+
path = gs_path.replace("gs://", "")
38+
39+
# Split on the first slash
40+
parts = path.split("/", 1)
41+
42+
bucket_name = parts[0]
43+
prefix = parts[1] if len(parts) > 1 else ""
44+
45+
return bucket_name, prefix
46+
47+
3548
def download_file(
3649
repo_name, file_name, revision_name=None, key_file="/app/data/service_account.json"
3750
):
3851
# Check if repo_name starts with "gs://"
3952
if "gs://" in repo_name:
4053
# Create directory if not exist
54+
bucket_name, _ = split_gs_path(repo_name)
4155
repo_name = repo_name.replace("gs://", "")
42-
cache_dir = Path(f"/app/hf_cache/{repo_name}")
56+
cache_dir = Path(f"/app/hf_cache/{bucket_name}")
4357
cache_dir.mkdir(parents=True, exist_ok=True)
4458

4559
# Connect to GCS storage
4660
try:
4761
storage_client = storage.Client.from_service_account_json(key_file)
4862
bucket = storage_client.bucket(repo_name)
4963
blob = bucket.blob(file_name)
64+
5065
dst_file = Path(f"{cache_dir}/{file_name}")
5166
if not dst_file.parent.exists():
5267
dst_file.parent.mkdir(parents=True)

truss/contexts/image_builder/serving_image_builder.py

+3
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ def list_bucket_files(bucket_name, data_dir, is_trusted=False):
114114

115115
all_objects = []
116116
for blob in blobs:
117+
# leave out folders
118+
if blob.name[-1] == "/":
119+
continue
117120
all_objects.append(blob.name)
118121

119122
return all_objects

truss/tests/contexts/image_builder/test_serving_image_builder.py

+38
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,44 @@ def test_correct_gcs_files_accessed_for_caching(mock_list_bucket_files):
163163
assert "fake_model-001-of-002.bin" in model_files[model]["files"]
164164

165165

166+
@patch("truss.contexts.image_builder.serving_image_builder.list_bucket_files")
167+
def test_correct_nested_gcs_files_accessed_for_caching(mock_list_bucket_files):
168+
mock_list_bucket_files.return_value = [
169+
"folder_a/folder_b/fake_model-001-of-002.bin",
170+
"folder_a/folder_b/fake_model-002-of-002.bin",
171+
]
172+
model = "gs://crazy-good-new-model-7b/folder_a/folder_b"
173+
174+
config = TrussConfig(
175+
python_version="py39",
176+
hf_cache=HuggingFaceCache(models=[HuggingFaceModel(repo_id=model)]),
177+
)
178+
179+
with TemporaryDirectory() as tmp_dir:
180+
truss_path = Path(tmp_dir)
181+
build_path = truss_path / "build"
182+
build_path.mkdir(parents=True, exist_ok=True)
183+
184+
model_files, files_to_cache = get_files_to_cache(config, truss_path, build_path)
185+
print(files_to_cache)
186+
187+
assert (
188+
"/app/hf_cache/crazy-good-new-model-7b/folder_a/folder_b/fake_model-001-of-002.bin"
189+
in files_to_cache
190+
)
191+
assert (
192+
"/app/hf_cache/crazy-good-new-model-7b/folder_a/folder_b/fake_model-002-of-002.bin"
193+
in files_to_cache
194+
)
195+
196+
assert (
197+
"folder_a/folder_b/fake_model-001-of-002.bin" in model_files[model]["files"]
198+
)
199+
assert (
200+
"folder_a/folder_b/fake_model-001-of-002.bin" in model_files[model]["files"]
201+
)
202+
203+
166204
@pytest.mark.integration
167205
def test_tgi_caching_truss():
168206
with ensure_kill_all():

0 commit comments

Comments
 (0)