More generic image type for OCI-compliant container technologies

Signed-off-by: Yuan Tang <terrytangyuan@gmail.com>
This commit is contained in:
Yuan Tang 2025-01-16 22:32:56 -05:00
parent 9f14382d82
commit 2deac4879f
No known key found for this signature in database
28 changed files with 55 additions and 55 deletions

View file

@ -1,6 +1,6 @@
version: '2' version: '2'
image_name: local image_name: local
docker_image: null container_image: null
conda_env: local conda_env: local
apis: apis:
- shields - shields

View file

@ -1,6 +1,6 @@
version: '2' version: '2'
image_name: local image_name: local
docker_image: null container_image: null
conda_env: local conda_env: local
apis: apis:
- shields - shields

View file

@ -1,6 +1,6 @@
version: '2' version: '2'
image_name: local image_name: local
docker_image: null container_image: null
conda_env: local conda_env: local
apis: apis:
- shields - shields

View file

@ -481,7 +481,7 @@
"- telemetry\n", "- telemetry\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: <span style=\"font-weight: bold\">[]</span>\n", "datasets: <span style=\"font-weight: bold\">[]</span>\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: <span style=\"font-weight: bold\">[]</span>\n", "eval_tasks: <span style=\"font-weight: bold\">[]</span>\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: <span style=\"font-weight: bold\">[]</span>\n", "memory_banks: <span style=\"font-weight: bold\">[]</span>\n",
@ -600,7 +600,7 @@
"- telemetry\n", "- telemetry\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",

View file

@ -358,7 +358,7 @@
"- telemetry\n", "- telemetry\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: <span style=\"font-weight: bold\">[]</span>\n", "datasets: <span style=\"font-weight: bold\">[]</span>\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: <span style=\"font-weight: bold\">[]</span>\n", "eval_tasks: <span style=\"font-weight: bold\">[]</span>\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: <span style=\"font-weight: bold\">[]</span>\n", "memory_banks: <span style=\"font-weight: bold\">[]</span>\n",
@ -486,7 +486,7 @@
"- telemetry\n", "- telemetry\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",

View file

@ -760,7 +760,7 @@
"- tool_runtime\n", "- tool_runtime\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: <span style=\"font-weight: bold\">[]</span>\n", "datasets: <span style=\"font-weight: bold\">[]</span>\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: <span style=\"font-weight: bold\">[]</span>\n", "eval_tasks: <span style=\"font-weight: bold\">[]</span>\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: <span style=\"font-weight: bold\">[]</span>\n", "memory_banks: <span style=\"font-weight: bold\">[]</span>\n",
@ -942,7 +942,7 @@
"- tool_runtime\n", "- tool_runtime\n",
"conda_env: together\n", "conda_env: together\n",
"datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "datasets: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"docker_image: null\n", "container_image: null\n",
"eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "eval_tasks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",
"image_name: together\n", "image_name: together\n",
"memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n", "memory_banks: \u001b[1m[\u001b[0m\u001b[1m]\u001b[0m\n",

View file

@ -19,11 +19,11 @@ llama stack build -h
We will start build our distribution (in the form of a Conda environment, or Docker image). In this step, we will specify: We will start build our distribution (in the form of a Conda environment, or Docker image). In this step, we will specify:
- `name`: the name for our distribution (e.g. `my-stack`) - `name`: the name for our distribution (e.g. `my-stack`)
- `image_type`: our build image type (`conda | docker`) - `image_type`: our build image type (`conda | container`)
- `distribution_spec`: our distribution specs for specifying API providers - `distribution_spec`: our distribution specs for specifying API providers
- `description`: a short description of the configurations for the distribution - `description`: a short description of the configurations for the distribution
- `providers`: specifies the underlying implementation for serving each API endpoint - `providers`: specifies the underlying implementation for serving each API endpoint
- `image_type`: `conda` | `docker` to specify whether to build the distribution in the form of Docker image or Conda environment. - `image_type`: `conda` | `container` to specify whether to build the distribution in the form of Docker image or Conda environment.
After this step is complete, a file named `<name>-build.yaml` and template file `<name>-run.yaml` will be generated and saved at the output file path specified at the end of the command. After this step is complete, a file named `<name>-build.yaml` and template file `<name>-run.yaml` will be generated and saved at the output file path specified at the end of the command.

View file

@ -182,8 +182,8 @@ def _generate_run_config(
""" """
apis = list(build_config.distribution_spec.providers.keys()) apis = list(build_config.distribution_spec.providers.keys())
run_config = StackRunConfig( run_config = StackRunConfig(
docker_image=( container_image=(
image_name if build_config.image_type == ImageType.docker.value else None image_name if build_config.image_type == ImageType.container.value else None
), ),
image_name=image_name, image_name=image_name,
apis=apis, apis=apis,
@ -238,7 +238,7 @@ def _run_stack_build_command_from_build_config(
image_name: Optional[str] = None, image_name: Optional[str] = None,
template_name: Optional[str] = None, template_name: Optional[str] = None,
) -> None: ) -> None:
if build_config.image_type == ImageType.docker.value: if build_config.image_type == ImageType.container.value:
if template_name: if template_name:
image_name = f"distribution-{template_name}" image_name = f"distribution-{template_name}"
else: else:

View file

@ -47,8 +47,8 @@ class StackBuild(Subcommand):
self.parser.add_argument( self.parser.add_argument(
"--image-type", "--image-type",
type=str, type=str,
help="Image Type to use for the build. This can be either conda or docker. If not specified, will use the image type from the template config.", help="Image Type to use for the build. This can be either conda or container or venv. If not specified, will use the image type from the template config.",
choices=["conda", "docker", "venv"], choices=["conda", "container", "venv"],
default="conda", default="conda",
) )

View file

@ -94,7 +94,7 @@ class StackRun(Subcommand):
if not config_file.exists() and not has_yaml_suffix: if not config_file.exists() and not has_yaml_suffix:
# check if it's a build config saved to docker dir # check if it's a build config saved to docker dir
config_file = Path( config_file = Path(
BUILDS_BASE_DIR / ImageType.docker.value / f"{args.config}-run.yaml" BUILDS_BASE_DIR / ImageType.container.value / f"{args.config}-run.yaml"
) )
if not config_file.exists() and not has_yaml_suffix: if not config_file.exists() and not has_yaml_suffix:
@ -115,12 +115,12 @@ class StackRun(Subcommand):
config_dict = yaml.safe_load(config_file.read_text()) config_dict = yaml.safe_load(config_file.read_text())
config = parse_and_maybe_upgrade_config(config_dict) config = parse_and_maybe_upgrade_config(config_dict)
if config.docker_image: if config.container_image:
script = ( script = (
importlib.resources.files("llama_stack") importlib.resources.files("llama_stack")
/ "distribution/start_container.sh" / "distribution/start_container.sh"
) )
run_args = [script, config.docker_image] run_args = [script, config.container_image]
else: else:
current_conda_env = os.environ.get("CONDA_DEFAULT_ENV") current_conda_env = os.environ.get("CONDA_DEFAULT_ENV")
image_name = args.image_name or current_conda_env image_name = args.image_name or current_conda_env

View file

@ -38,7 +38,7 @@ SERVER_DEPENDENCIES = [
class ImageType(Enum): class ImageType(Enum):
docker = "docker" container = "container"
conda = "conda" conda = "conda"
venv = "venv" venv = "venv"
@ -77,7 +77,7 @@ def get_provider_dependencies(
provider_spec = providers_for_api[provider_type] provider_spec = providers_for_api[provider_type]
deps.extend(provider_spec.pip_packages) deps.extend(provider_spec.pip_packages)
if provider_spec.docker_image: if provider_spec.container_image:
raise ValueError("A stack's dependencies cannot have a docker image") raise ValueError("A stack's dependencies cannot have a docker image")
normal_deps = [] normal_deps = []
@ -109,23 +109,23 @@ def build_image(
image_name: str, image_name: str,
template_name: Optional[str] = None, template_name: Optional[str] = None,
): ):
docker_image = build_config.distribution_spec.docker_image or "python:3.10-slim" container_image = build_config.distribution_spec.container_image or "python:3.10-slim"
normal_deps, special_deps = get_provider_dependencies( normal_deps, special_deps = get_provider_dependencies(
build_config.distribution_spec.providers build_config.distribution_spec.providers
) )
normal_deps += SERVER_DEPENDENCIES normal_deps += SERVER_DEPENDENCIES
if build_config.image_type == ImageType.docker.value: if build_config.image_type == ImageType.container.value:
script = str( script = str(
importlib.resources.files("llama_stack") / "distribution/build_container.sh" importlib.resources.files("llama_stack") / "distribution/build_container.sh"
) )
args = [ args = [
script, script,
image_name, image_name,
docker_image, container_image,
str(build_file_path), str(build_file_path),
str(BUILDS_BASE_DIR / ImageType.docker.value), str(BUILDS_BASE_DIR / ImageType.container.value),
" ".join(normal_deps), " ".join(normal_deps),
] ]
elif build_config.image_type == ImageType.conda.value: elif build_config.image_type == ImageType.conda.value:

View file

@ -24,7 +24,7 @@ if [ $# -lt 2 ]; then
exit 1 exit 1
fi fi
docker_image="$1" container_image="$1"
host_build_dir="$2" host_build_dir="$2"
container_build_dir="/app/builds" container_build_dir="/app/builds"
@ -43,5 +43,5 @@ $DOCKER_BINARY run $DOCKER_OPTS -it \
--entrypoint "/usr/local/bin/llama" \ --entrypoint "/usr/local/bin/llama" \
-v $host_build_dir:$container_build_dir \ -v $host_build_dir:$container_build_dir \
$mounts \ $mounts \
$docker_image \ $container_image \
stack configure ./llamastack-build.yaml --output-dir $container_build_dir stack configure ./llamastack-build.yaml --output-dir $container_build_dir

View file

@ -73,7 +73,7 @@ class AutoRoutedProviderSpec(ProviderSpec):
provider_type: str = "router" provider_type: str = "router"
config_class: str = "" config_class: str = ""
docker_image: Optional[str] = None container_image: Optional[str] = None
routing_table_api: Api routing_table_api: Api
module: str module: str
provider_data_validator: Optional[str] = Field( provider_data_validator: Optional[str] = Field(
@ -89,7 +89,7 @@ class AutoRoutedProviderSpec(ProviderSpec):
class RoutingTableProviderSpec(ProviderSpec): class RoutingTableProviderSpec(ProviderSpec):
provider_type: str = "routing_table" provider_type: str = "routing_table"
config_class: str = "" config_class: str = ""
docker_image: Optional[str] = None container_image: Optional[str] = None
router_api: Api router_api: Api
module: str module: str
@ -101,7 +101,7 @@ class DistributionSpec(BaseModel):
default="", default="",
description="Description of the distribution", description="Description of the distribution",
) )
docker_image: Optional[str] = None container_image: Optional[str] = None
providers: Dict[str, Union[str, List[str]]] = Field( providers: Dict[str, Union[str, List[str]]] = Field(
default_factory=dict, default_factory=dict,
description=""" description="""
@ -127,9 +127,9 @@ Reference to the distribution this package refers to. For unregistered (adhoc) p
this could be just a hash this could be just a hash
""", """,
) )
docker_image: Optional[str] = Field( container_image: Optional[str] = Field(
default=None, default=None,
description="Reference to the docker image if this package refers to a container", description="Reference to the container image if this package refers to a container",
) )
apis: List[str] = Field( apis: List[str] = Field(
default_factory=list, default_factory=list,
@ -168,5 +168,5 @@ class BuildConfig(BaseModel):
) )
image_type: str = Field( image_type: str = Field(
default="conda", default="conda",
description="Type of package to build (conda | docker | venv)", description="Type of package to build (conda | container | venv)",
) )

View file

@ -31,7 +31,7 @@ if [ $# -lt 3 ]; then
fi fi
build_name="$1" build_name="$1"
docker_image="localhost/distribution-$build_name" container_image="localhost/distribution-$build_name"
shift shift
yaml_config="$1" yaml_config="$1"
@ -92,4 +92,4 @@ $DOCKER_BINARY run $DOCKER_OPTS -it \
$mounts \ $mounts \
--env LLAMA_STACK_PORT=$port \ --env LLAMA_STACK_PORT=$port \
--entrypoint='["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]' \ --entrypoint='["python", "-m", "llama_stack.distribution.server.server", "--yaml-config", "/app/config.yaml"]' \
$docker_image:$version_tag $container_image:$version_tag

View file

@ -147,11 +147,11 @@ class InlineProviderSpec(ProviderSpec):
default_factory=list, default_factory=list,
description="The pip dependencies needed for this implementation", description="The pip dependencies needed for this implementation",
) )
docker_image: Optional[str] = Field( container_image: Optional[str] = Field(
default=None, default=None,
description=""" description="""
The docker image to use for this implementation. If one is provided, pip_packages will be ignored. The docker image to use for this implementation. If one is provided, pip_packages will be ignored.
If a provider depends on other providers, the dependencies MUST NOT specify a docker image. If a provider depends on other providers, the dependencies MUST NOT specify a container image.
""", """,
) )
module: str = Field( module: str = Field(
@ -194,7 +194,7 @@ API responses, specify the adapter here.
) )
@property @property
def docker_image(self) -> Optional[str]: def container_image(self) -> Optional[str]:
return None return None
@property @property

View file

@ -70,7 +70,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use AWS Bedrock for running LLM inference and safety", description="Use AWS Bedrock for running LLM inference and safety",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=default_models, default_models=default_models,

View file

@ -92,7 +92,7 @@ def get_distribution_template() -> DistributionTemplate:
name="cerebras", name="cerebras",
distro_type="self_hosted", distro_type="self_hosted",
description="Use Cerebras for running LLM inference", description="Use Cerebras for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=default_models, default_models=default_models,

View file

@ -2,7 +2,7 @@ version: '2'
name: experimental-post-training name: experimental-post-training
distribution_spec: distribution_spec:
description: Experimental template for post training description: Experimental template for post training
docker_image: null container_image: null
providers: providers:
inference: inference:
- inline::meta-reference - inline::meta-reference

View file

@ -1,6 +1,6 @@
version: '2' version: '2'
image_name: experimental-post-training image_name: experimental-post-training
docker_image: null container_image: null
conda_env: experimental-post-training conda_env: experimental-post-training
apis: apis:
- agents - agents

View file

@ -98,7 +98,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use Fireworks.AI for running LLM inference", description="Use Fireworks.AI for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=default_models, default_models=default_models,

View file

@ -88,7 +88,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use (an external) Hugging Face Inference Endpoint for running LLM inference", description="Use (an external) Hugging Face Inference Endpoint for running LLM inference",
docker_image=None, container_image=None,
template_path=None, template_path=None,
providers=providers, providers=providers,
default_models=[inference_model, safety_model], default_models=[inference_model, safety_model],

View file

@ -89,7 +89,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use (an external) Hugging Face Inference Endpoint for running LLM inference", description="Use (an external) Hugging Face Inference Endpoint for running LLM inference",
docker_image=None, container_image=None,
template_path=None, template_path=None,
providers=providers, providers=providers,
default_models=[inference_model, safety_model], default_models=[inference_model, safety_model],

View file

@ -68,7 +68,7 @@ def get_distribution_template() -> DistributionTemplate:
name="nvidia", name="nvidia",
distro_type="remote_hosted", distro_type="remote_hosted",
description="Use NVIDIA NIM for running LLM inference", description="Use NVIDIA NIM for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=default_models, default_models=default_models,

View file

@ -90,7 +90,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use (an external) Ollama server for running LLM inference", description="Use (an external) Ollama server for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=[inference_model, safety_model], default_models=[inference_model, safety_model],

View file

@ -37,7 +37,7 @@ class RunConfigSettings(BaseModel):
self, self,
name: str, name: str,
providers: Dict[str, List[str]], providers: Dict[str, List[str]],
docker_image: Optional[str] = None, container_image: Optional[str] = None,
) -> StackRunConfig: ) -> StackRunConfig:
provider_registry = get_provider_registry() provider_registry = get_provider_registry()
@ -83,7 +83,7 @@ class RunConfigSettings(BaseModel):
return StackRunConfig( return StackRunConfig(
image_name=name, image_name=name,
docker_image=docker_image, container_image=container_image,
conda_env=name, conda_env=name,
apis=apis, apis=apis,
providers=provider_configs, providers=provider_configs,
@ -113,7 +113,7 @@ class DistributionTemplate(BaseModel):
# Optional configuration # Optional configuration
run_config_env_vars: Optional[Dict[str, Tuple[str, str]]] = None run_config_env_vars: Optional[Dict[str, Tuple[str, str]]] = None
docker_image: Optional[str] = None container_image: Optional[str] = None
default_models: Optional[List[ModelInput]] = None default_models: Optional[List[ModelInput]] = None
@ -122,7 +122,7 @@ class DistributionTemplate(BaseModel):
name=self.name, name=self.name,
distribution_spec=DistributionSpec( distribution_spec=DistributionSpec(
description=self.description, description=self.description,
docker_image=self.docker_image, container_image=self.container_image,
providers=self.providers, providers=self.providers,
), ),
image_type="conda", # default to conda, can be overridden image_type="conda", # default to conda, can be overridden
@ -170,7 +170,7 @@ class DistributionTemplate(BaseModel):
for yaml_pth, settings in self.run_configs.items(): for yaml_pth, settings in self.run_configs.items():
run_config = settings.run_config( run_config = settings.run_config(
self.name, self.providers, self.docker_image self.name, self.providers, self.container_image
) )
with open(yaml_output_dir / yaml_pth, "w") as f: with open(yaml_output_dir / yaml_pth, "w") as f:
yaml.safe_dump( yaml.safe_dump(

View file

@ -92,7 +92,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use (an external) TGI server for running LLM inference", description="Use (an external) TGI server for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=[inference_model, safety_model], default_models=[inference_model, safety_model],

View file

@ -96,7 +96,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use Together.AI for running LLM inference", description="Use Together.AI for running LLM inference",
docker_image=None, container_image=None,
template_path=Path(__file__).parent / "doc_template.md", template_path=Path(__file__).parent / "doc_template.md",
providers=providers, providers=providers,
default_models=default_models, default_models=default_models,

View file

@ -84,7 +84,7 @@ def get_distribution_template() -> DistributionTemplate:
name=name, name=name,
distro_type="self_hosted", distro_type="self_hosted",
description="Use a built-in vLLM engine for running LLM inference", description="Use a built-in vLLM engine for running LLM inference",
docker_image=None, container_image=None,
template_path=None, template_path=None,
providers=providers, providers=providers,
default_models=[inference_model], default_models=[inference_model],