truss 0.11.13rc4__py3-none-any.whl → 0.11.14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of truss might be problematic. Click here for more details.

truss/base/constants.py CHANGED
@@ -49,6 +49,7 @@ FILENAME_CONSTANTS_MAP = {
49
49
  }
50
50
 
51
51
  SERVER_DOCKERFILE_TEMPLATE_NAME = "server.Dockerfile.jinja"
52
+ NO_BUILD_DOCKERFILE_TEMPLATE_NAME = "no_build.Dockerfile.jinja"
52
53
  MODEL_DOCKERFILE_NAME = "Dockerfile"
53
54
  MODEL_CACHE_PATH = pathlib.Path("/app/model_cache")
54
55
  README_TEMPLATE_NAME = "README.md.jinja"
@@ -541,11 +541,19 @@ class BaseImage(custom_types.ConfigModel):
541
541
 
542
542
 
543
543
  class DockerServer(custom_types.ConfigModel):
544
- start_command: str
544
+ start_command: Optional[str] = None
545
545
  server_port: int
546
546
  predict_endpoint: str
547
547
  readiness_endpoint: str
548
548
  liveness_endpoint: str
549
+ run_as_user_id: Optional[int] = None
550
+ no_build: Optional[bool] = None
551
+
552
+ @pydantic.model_validator(mode="after")
553
+ def _validate_start_command(self) -> "DockerServer":
554
+ if not self.no_build and self.start_command is None:
555
+ raise ValueError("start_command is required when no_build is not true")
556
+ return self
549
557
 
550
558
 
551
559
  class TrainingArtifactReference(custom_types.ConfigModel):
@@ -32,6 +32,7 @@ from truss.base.constants import (
32
32
  FILENAME_CONSTANTS_MAP,
33
33
  MODEL_CACHE_PATH,
34
34
  MODEL_DOCKERFILE_NAME,
35
+ NO_BUILD_DOCKERFILE_TEMPLATE_NAME,
35
36
  REQUIREMENTS_TXT_FILENAME,
36
37
  SERVER_CODE_DIR,
37
38
  SERVER_DOCKERFILE_TEMPLATE_NAME,
@@ -577,7 +578,10 @@ class ServingImageBuilder(ImageBuilder):
577
578
  else:
578
579
  self.prepare_trtllm_decoder_build_dir(build_dir=build_dir)
579
580
 
580
- if config.docker_server is not None:
581
+ if (
582
+ config.docker_server is not None
583
+ and config.docker_server.no_build is not True
584
+ ):
581
585
  self._copy_into_build_dir(
582
586
  TEMPLATES_DIR / "docker_server_requirements.txt",
583
587
  build_dir,
@@ -750,12 +754,21 @@ class ServingImageBuilder(ImageBuilder):
750
754
  build_commands: List[str],
751
755
  ):
752
756
  config = self._spec.config
757
+
753
758
  data_dir = build_dir / config.data_dir
754
759
  model_dir = build_dir / config.model_module_dir
755
760
  bundled_packages_dir = build_dir / config.bundled_packages_dir
756
- dockerfile_template = read_template_from_fs(
757
- TEMPLATES_DIR, SERVER_DOCKERFILE_TEMPLATE_NAME
758
- )
761
+
762
+ # Note: no-build deployment template doesn't use most of the template variables,
763
+ # because it tries to run the base image as-is to the extent possible.
764
+ if config.docker_server and config.docker_server.no_build:
765
+ dockerfile_template = read_template_from_fs(
766
+ TEMPLATES_DIR, NO_BUILD_DOCKERFILE_TEMPLATE_NAME
767
+ )
768
+ else:
769
+ dockerfile_template = read_template_from_fs(
770
+ TEMPLATES_DIR, SERVER_DOCKERFILE_TEMPLATE_NAME
771
+ )
759
772
  python_version = truss_config.to_dotted_python_version(config.python_version)
760
773
  if config.base_image:
761
774
  base_image_name_and_tag = config.base_image.image
@@ -115,9 +115,11 @@ WORKDIR $APP_HOME
115
115
  {% endblock %}
116
116
 
117
117
 
118
+ {% set packages_dir = "/packages" %}
119
+ RUN mkdir -p {{ packages_dir }}
118
120
  {% block bundled_packages_copy %}
119
121
  {%- if bundled_packages_dir_exists %}
120
- COPY --chown={{ default_owner }} ./{{ config.bundled_packages_dir }} /packages
122
+ COPY --chown={{ default_owner }} ./{{ config.bundled_packages_dir }} {{ packages_dir }}
121
123
  {%- endif %}
122
124
  {% endblock %}
123
125
 
@@ -0,0 +1 @@
1
+ FROM {{ config.base_image.image }}
@@ -104,7 +104,7 @@ COPY --chown={{ default_owner }} ./{{ config.model_module_dir }} ${APP_HOME}/mod
104
104
  {# Macro to change ownership of directories and switch to regular user #}
105
105
  {%- macro chown_and_switch_to_regular_user_if_enabled(additional_chown_dirs=[]) -%}
106
106
  {%- if non_root_user %}
107
- RUN chown -R {{ app_username }}:{{ app_username }} {% for dir in additional_chown_dirs %}{{ dir }} {% endfor %}${HOME} ${APP_HOME}
107
+ RUN chown -R {{ app_username }}:{{ app_username }} ${HOME} ${APP_HOME} {{ packages_dir }} {% for dir in additional_chown_dirs %}{{ dir }} {% endfor %}
108
108
  USER {{ app_username }}
109
109
  {%- endif %} {#- endif non_root_user #}
110
110
  {%- endmacro -%}
@@ -1,13 +1,12 @@
1
1
  import atexit
2
2
  import json
3
3
  import logging
4
- import os
5
4
  import time
6
5
  from dataclasses import dataclass
7
6
  from functools import lru_cache
8
7
  from pathlib import Path
9
8
  from threading import Lock, Thread
10
- from typing import Optional, Union
9
+ from typing import List, Optional, Union
11
10
 
12
11
  try:
13
12
  from prometheus_client import Counter, Gauge, Histogram
@@ -31,7 +30,7 @@ class TrussTransferStats:
31
30
  total_manifest_size_bytes: int
32
31
  total_download_time_secs: float
33
32
  total_aggregated_mb_s: Optional[float]
34
- file_downloads: list[FileDownloadMetric]
33
+ file_downloads: List[FileDownloadMetric]
35
34
  b10fs_read_speed_mbps: Optional[float]
36
35
  b10fs_decision_to_use: bool
37
36
  b10fs_enabled: bool
@@ -70,7 +69,7 @@ class TrussTransferStats:
70
69
  except Exception:
71
70
  return None
72
71
 
73
- def publish_to_prometheus(self):
72
+ def publish_to_prometheus(self, hidden_time: float = 0.0):
74
73
  """Publish transfer stats to Prometheus metrics. Only runs once."""
75
74
  if not PROMETHEUS_AVAILABLE:
76
75
  return
@@ -93,10 +92,12 @@ class TrussTransferStats:
93
92
  download_time_histogram = Histogram(
94
93
  "model_cache_download_time_seconds",
95
94
  "Total download time in seconds",
96
- buckets=[
95
+ buckets=[0]
96
+ + [
97
97
  2**i
98
98
  for i in range(-3, 11) # = [0.125, .. 2048] seconds
99
- ],
99
+ ]
100
+ + [float("inf")],
100
101
  )
101
102
  download_speed_gauge = Gauge(
102
103
  "model_cache_download_speed_mbps", "Aggregated download speed in MB/s"
@@ -110,21 +111,29 @@ class TrussTransferStats:
110
111
  "model_cache_file_size_bytes_total",
111
112
  "Total size of downloaded files in bytes",
112
113
  )
114
+ file_download_hidden_time_gauge = Gauge(
115
+ "model_cache_file_download_hidden_time_seconds",
116
+ "Total time hidden from user by starting the import before user code (seconds)",
117
+ )
113
118
  file_download_time_histogram = Histogram(
114
119
  "model_cache_file_download_time_seconds",
115
120
  "File download time distribution",
116
- buckets=[
121
+ buckets=[0]
122
+ + [
117
123
  2**i
118
124
  for i in range(-3, 11) # = [0.125, .. 2048] seconds
119
- ],
125
+ ]
126
+ + [float("inf")],
120
127
  )
121
128
  file_download_speed_histogram = Histogram(
122
129
  "model_cache_file_download_speed_mbps",
123
130
  "File download speed distribution",
124
- buckets=[
131
+ buckets=[0]
132
+ + [
125
133
  2**i
126
134
  for i in range(-1, 12) # = [0.5, .. 4096] MB/s
127
- ],
135
+ ]
136
+ + [float("inf")],
128
137
  )
129
138
 
130
139
  # B10FS specific metrics
@@ -160,6 +169,7 @@ class TrussTransferStats:
160
169
  # Set main transfer metrics
161
170
  manifest_size_gauge.set(self.total_manifest_size_bytes)
162
171
  download_time_histogram.observe(self.total_download_time_secs)
172
+ file_download_hidden_time_gauge.set(hidden_time)
163
173
 
164
174
  if self.total_aggregated_mb_s is not None:
165
175
  download_speed_gauge.set(self.total_aggregated_mb_s)
@@ -338,10 +348,7 @@ class LazyDataResolverV2:
338
348
  if stats and publish_stats:
339
349
  self.logger.info(f"model_cache: {stats}")
340
350
  # Publish stats to Prometheus
341
- if (
342
- os.getenv("TRUSS_MODEL_CACHE_PROMETHEUS", "0") == "1"
343
- ): # Hide behind feature flag for core-product to enabled.
344
- stats.publish_to_prometheus()
351
+ stats.publish_to_prometheus()
345
352
  self.logger.info(
346
353
  f"model_cache: Fetch took {fetch_t:.2f} seconds, of which {start_lock_t:.2f} seconds were spent blocking."
347
354
  )
@@ -36,6 +36,7 @@ COPY --chown= ./data ${APP_HOME}/data
36
36
  COPY --chown= ./server ${APP_HOME}
37
37
  COPY --chown= ./config.yaml ${APP_HOME}/config.yaml
38
38
  COPY --chown= ./model ${APP_HOME}/model
39
+ RUN mkdir -p /packages
39
40
  COPY --chown= ./packages /packages
40
41
  ENV INFERENCE_SERVER_PORT="8080"
41
42
  ENV SERVER_START_CMD="/usr/local/bin/python3 /app/main.py"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: truss
3
- Version: 0.11.13rc4
3
+ Version: 0.11.14
4
4
  Summary: A seamless bridge from model development to model delivery
5
5
  Project-URL: Repository, https://github.com/basetenlabs/truss
6
6
  Project-URL: Homepage, https://truss.baseten.co
@@ -2,11 +2,11 @@ truss/__init__.py,sha256=CoUcP6vx_pocyemRmpbCPlndkHhdMkABAlr0ZXVuPCk,1163
2
2
  truss/api/__init__.py,sha256=5GTE2rlupet-beaawUr0FPyDPEJ9UyBTUpJmCE3RGfc,5453
3
3
  truss/api/definitions.py,sha256=QAaIBqL59Q-R7HtLcXcoeCIWBN2HqOzApdFX0PpCq2s,1604
4
4
  truss/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- truss/base/constants.py,sha256=sExArdnuGg83z83XMgaQ4b8SS3V_j_bJEpOATDGJzpE,3600
5
+ truss/base/constants.py,sha256=yFvDVyWMqeAsWOfKUKJVUNbH26N2JZKDqgxmRSe4EWk,3664
6
6
  truss/base/custom_types.py,sha256=FUSIT2lPOQb6gfg6IzT63YBV8r8L6NIZ0D74Fp3e_jQ,2835
7
7
  truss/base/errors.py,sha256=zDVLEvseTChdPP0oNhBBQCtQUtZJUaof5zeWMIjqz6o,691
8
8
  truss/base/trt_llm_config.py,sha256=rEtBVFg2QnNMxnaz11s5Z69dJB1w7Bpt48Wf6jSsVZI,33087
9
- truss/base/truss_config.py,sha256=7CtiJIwMHtDU8Wzn8UTJUVVunD0pWFl4QUVycK2aIpY,28055
9
+ truss/base/truss_config.py,sha256=s39Xc1e20s8IV07YLl_aVnp-uRS18ZQ2TV-3FILx4nY,28416
10
10
  truss/base/truss_spec.py,sha256=jFVF79CXoEEspl2kXBAPyi-rwISReIGTdobGpaIhwJw,5979
11
11
  truss/cli/chains_commands.py,sha256=Kpa5mCg6URAJQE2ZmZfVQFhjBHEitKT28tKiW0H6XAI,17406
12
12
  truss/cli/cli.py,sha256=PaMkuwXZflkU7sa1tEoT_Zmy-iBkEZs1m4IVqcieaeo,30367
@@ -36,7 +36,7 @@ truss/contexts/docker_build_setup.py,sha256=cF4ExZgtYvrWxvyCAaUZUvV_DB_7__MqVomU
36
36
  truss/contexts/truss_context.py,sha256=uS6L-ACHxNk0BsJwESOHh1lA0OGGw0pb33aFKGsASj4,436
37
37
  truss/contexts/image_builder/cache_warmer.py,sha256=TGMV1Mh87n2e_dSowH0sf0rZhZraDOR-LVapZL3a5r8,7377
38
38
  truss/contexts/image_builder/image_builder.py,sha256=IuRgDeeoHVLzIkJvKtX3807eeqEyaroCs_KWDcIHZUg,1461
39
- truss/contexts/image_builder/serving_image_builder.py,sha256=n6MTHMZsANSTGXPfkKDJ1Ch4fEc6HIjbOXA_1B9zt9Q,33438
39
+ truss/contexts/image_builder/serving_image_builder.py,sha256=1PfHtkTEdNPhSQAX8Ajk_0LN3KR2EfLKwOJsnECtKXQ,33958
40
40
  truss/contexts/image_builder/util.py,sha256=y2-CjUKv0XV-0w2sr1fUCflysDJLsoU4oPp6tvvoFnk,1203
41
41
  truss/contexts/local_loader/docker_build_emulator.py,sha256=3n0eIlJblz_sldh4AN8AHQDyfjQGdYyld5FabBdd9wE,3563
42
42
  truss/contexts/local_loader/dockerfile_parser.py,sha256=GoRJ0Af_3ILyLhjovK5lrCGn1rMxz6W3l681ro17ZzI,1344
@@ -66,12 +66,13 @@ truss/remote/baseten/utils/time.py,sha256=Ry9GMjYnbIGYVIGwtmv4V8ljWjvdcaCf5NOQzl
66
66
  truss/remote/baseten/utils/transfer.py,sha256=d3VptuQb6M1nyS6kz0BAfeOYDLkMKUjatJXpY-mp-As,1548
67
67
  truss/templates/README.md.jinja,sha256=N7CJdyldZuJamj5jLh47le0hFBdu9irVsTBqoxhPNPQ,2476
68
68
  truss/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
- truss/templates/base.Dockerfile.jinja,sha256=DgvNqmkt5QRrqy7a9hw6HffmVTUrdGl06oVZ4eeha5Y,5253
69
+ truss/templates/base.Dockerfile.jinja,sha256=tdMmK5TeiQuYbz4gqbACM3R-l-mazqL9tAZtJ4sxC4g,5331
70
70
  truss/templates/cache.Dockerfile.jinja,sha256=1qZqDo1phrcqi-Vwol-VafYJkADsBbQWU6huQ-_1x00,1146
71
71
  truss/templates/cache_requirements.txt,sha256=xoPoJ-OVnf1z6oq_RVM3vCr3ionByyqMLj7wGs61nUs,87
72
72
  truss/templates/copy_cache_files.Dockerfile.jinja,sha256=Os5zFdYLZ_AfCRGq4RcpVTObOTwL7zvmwYcvOzd_Zqo,126
73
73
  truss/templates/docker_server_requirements.txt,sha256=PyhOPKAmKW1N2vLvTfLMwsEtuGpoRrbWuNo7tT6v2Mc,18
74
- truss/templates/server.Dockerfile.jinja,sha256=FdxCIXBjBMXVQy0fFxEY2acL-MAZGOD8JKKWAhu3M24,7071
74
+ truss/templates/no_build.Dockerfile.jinja,sha256=8x2PJUxr_gHai0St8ue2aWyih36t8kBytXMGr_5LG4w,35
75
+ truss/templates/server.Dockerfile.jinja,sha256=Mu5_ZxuAknwaEOsF0l-XssA9pDg3pD3eLl6JBzNJ4rg,7091
75
76
  truss/templates/control/requirements.txt,sha256=tJGr83WoE0CZm2FrloZ9VScK84q-_FTuVXjDYrexhW0,250
76
77
  truss/templates/control/control/application.py,sha256=5Kam6M-XtfKGaXQz8cc3d0bwDkB80o2MskABWROx1gk,5321
77
78
  truss/templates/control/control/endpoints.py,sha256=KzqsLVNJE6r6TCPW8D5FMCtsfHadTwR15A3z_viGxmM,11782
@@ -107,7 +108,7 @@ truss/templates/server/common/tracing.py,sha256=XSTXNoRtV8vXwveJoX3H32go0JKnLmzn
107
108
  truss/templates/server/common/patches/whisper/patch.py,sha256=kDECQ-wmEpeAZFhUTQP457ofueeMsm7DgNy9tqinhJQ,2383
108
109
  truss/templates/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
109
110
  truss/templates/shared/dynamic_config_resolver.py,sha256=75s42NFhQI5jL7BqlJH_UkuQS7ptbtFh13f2nh6X5Wo,920
110
- truss/templates/shared/lazy_data_resolver.py,sha256=2QS_0Qac5MMJYhzW-DGgs9_Wh7BtIGLfBtnm29I7X8o,13818
111
+ truss/templates/shared/lazy_data_resolver.py,sha256=HxrZz6X30j2LbsExYSqhuOGoYEffGpd7FPBtJexI7TQ,14064
111
112
  truss/templates/shared/log_config.py,sha256=l9udyu4VKHZePlfK9LQEd5TOUUodPuehypsXRSUL4Ac,5411
112
113
  truss/templates/shared/secrets_resolver.py,sha256=3prDe3Q06NTmUEe7KCW-W4TD1CzGck9lpDG789209z4,2110
113
114
  truss/templates/shared/serialization.py,sha256=_WC_2PPkRi-MdTwxwjG8LKQptnHi4sANfpOlKWevqWc,3736
@@ -185,7 +186,7 @@ truss/tests/test_data/pima-indians-diabetes.csv,sha256=BvW3ws17ymhv2k-S6rX2Hn_2Q
185
186
  truss/tests/test_data/readme_int_example.md,sha256=fuHvpLtdkJy1f4NAR_djotVBdzusHYNXc-Fwh588XAE,1586
186
187
  truss/tests/test_data/readme_no_example.md,sha256=T2CzFMRvICXeX3_5XbFoqhHchcHGot-xM7izx34B3aQ,1607
187
188
  truss/tests/test_data/readme_str_example.md,sha256=fP4pvMqgLdIapaOf_BgRiV0H7pw4so0RNxrlq5lbROE,1726
188
- truss/tests/test_data/server.Dockerfile,sha256=3rWiU3RxBh0PIh8pS23FnP8UA-ErmzxTlgf_J22mMQ8,2024
189
+ truss/tests/test_data/server.Dockerfile,sha256=KoQN5qBpiXL93qbjbG76kfRVapwfV5CNJzQcpjPocz0,2047
189
190
  truss/tests/test_data/annotated_types_truss/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
190
191
  truss/tests/test_data/annotated_types_truss/config.yaml,sha256=B-ZyyjLLqtxGfXj2tkH68Hy7NOMB_coYvoWyWom61g0,147
191
192
  truss/tests/test_data/annotated_types_truss/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -370,8 +371,8 @@ truss_train/deployment.py,sha256=lWWANSuzBWu2M4oK4qD7n-oVR1JKdmw2Pn5BJQHg-Ck,307
370
371
  truss_train/loader.py,sha256=0o66EjBaHc2YY4syxxHVR4ordJWs13lNXnKjKq2wq0U,1630
371
372
  truss_train/public_api.py,sha256=9N_NstiUlmBuLUwH_fNG_1x7OhGCytZLNvqKXBlStrM,1220
372
373
  truss_train/restore_from_checkpoint.py,sha256=8hdPm-WSgkt74HDPjvCjZMBpvA9MwtoYsxVjOoa7BaM,1176
373
- truss-0.11.13rc4.dist-info/METADATA,sha256=xxM0NsWyJwukE2KXOuzkZ--EuVl7gRNiJw2wBFwpPT0,6681
374
- truss-0.11.13rc4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
375
- truss-0.11.13rc4.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
376
- truss-0.11.13rc4.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
377
- truss-0.11.13rc4.dist-info/RECORD,,
374
+ truss-0.11.14.dist-info/METADATA,sha256=3F8SLMvpqzqYhOb4WB0Ngy_eFRBS_AJqhHtfy4j73DQ,6678
375
+ truss-0.11.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
376
+ truss-0.11.14.dist-info/entry_points.txt,sha256=-MwKfHHQHQ6j0HqIgvxrz3CehCmczDLTD-OsRHnjjuU,130
377
+ truss-0.11.14.dist-info/licenses/LICENSE,sha256=FTqGzu85i-uw1Gi8E_o0oD60bH9yQ_XIGtZbA1QUYiw,1064
378
+ truss-0.11.14.dist-info/RECORD,,