Skip to content
This repository was archived by the owner on Sep 20, 2025. It is now read-only.
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,6 @@ emd_models/
**artifacts
src/pipeline/emd
*.log
.venv
.idea
.venv-*
Binary file removed assets/s5cmd
Binary file not shown.
Binary file removed docs/images/emd-deploy.gif
Binary file not shown.
Binary file removed docs/images/status.png
Binary file not shown.
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ readme = "README.md"
[tool.poetry]
packages = [
{ include = "**/*", from = "src/emd", to = "emd" },
{ include = "pipeline", from = "src", to = "emd" },
{ include = "s5cmd", from = "assets", to = "emd/pipeline" }
{ include = "pipeline", from = "src", to = "emd" }
]
exclude = [".venv"]

Expand Down
11 changes: 11 additions & 0 deletions src/emd/cfn/codepipeline/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ Resources:
export PYTHONPATH=.:$PYTHONPATH
pip install --upgrade pip
pip install -r requirements.txt
# Download and setup s5cmd
echo "Downloading s5cmd..."
if [[ "$region" == cn-* ]]; then
s5cmd_url="https://aws-gcr-solutions-cn-north-1.s3.cn-north-1.amazonaws.com.cn/easy-model-deployer/pipeline/s5cmd.zip"
else
s5cmd_url="https://aws-gcr-solutions-us-east-1.s3.us-east-1.amazonaws.com/easy-model-deployer/pipeline/s5cmd.zip"
fi
curl -L -o s5cmd.zip "$s5cmd_url"
unzip -o s5cmd.zip
chmod +x s5cmd
echo "s5cmd setup completed"
python pipeline.py --region $region --model_id $model_id --model_tag $ModelTag --framework_type $FrameworkType --service_type $service --backend_type $backend_name --model_s3_bucket $model_s3_bucket --instance_type $instance_type --extra_params "$extra_params" --skip_deploy
# cd ..
echo model build pipeline completed on `date`
Expand Down
2 changes: 1 addition & 1 deletion src/emd/commands/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def bootstrap(
):

region = get_current_region()
typer.echo("AWS environment is properly configured.")
typer.echo("AWS environment configuration verified.")
layout["main"].update("[bold red]Initalizing environment...[/bold red]")
try:
bucket_name = get_bucket_name(
Expand Down
20 changes: 12 additions & 8 deletions src/emd/commands/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import questionary
from emd.utils.accelerator_utils import get_gpu_num,check_cuda_exists,check_neuron_exists
from emd.utils.decorators import catch_aws_credential_errors,check_emd_env_exist,load_aws_profile
from emd.utils.smart_bootstrap import smart_bootstrap_manager
from emd.utils.logger_utils import make_layout
from emd.utils.exceptions import ModelNotSupported,ServiceNotSupported,InstanceNotSupported
from prompt_toolkit import prompt
Expand Down Expand Up @@ -252,6 +253,9 @@ def deploy(
else:
region = get_current_region()

if region != LOCAL_REGION:
smart_bootstrap_manager.auto_bootstrap_if_needed(region)

if dockerfile_local_path:
response = sdk_deploy(
model_id='custom-docker',
Expand Down Expand Up @@ -571,13 +575,13 @@ def deploy(
engine_info_str = json.dumps(engine_info,indent=2,ensure_ascii=False)
framework_info_str = json.dumps(framework_info, indent=2, ensure_ascii=False)
extra_params_info = json.dumps(extra_params, indent=2, ensure_ascii=False)
console.print(f"[bold blue]Deployment parameters:[/bold blue]")
console.print(f"[bold blue]model_id: {model_id},model_tag: {model_tag}[/bold blue]")
console.print(f"[bold blue]instance_type: {instance_type}[/bold blue]")
console.print(f"[bold blue]service_type: {service_type}[/bold blue]")
console.print(f"[bold blue]engine info:\n {engine_info_str}[/bold blue]")
console.print(f"[bold blue]framework info:\n {framework_info_str}[/bold blue]")
console.print(f"[bold blue]extra_params:\n {extra_params_info}[/bold blue]")
console.print(f"[bold magenta]Deployment parameters:[/bold magenta]")
console.print(f"[bold cyan]model_id: {model_id}, model_tag: {model_tag}[/bold cyan]")
console.print(f"[bold cyan]instance_type: {instance_type}[/bold cyan]")
console.print(f"[bold cyan]service_type: {service_type}[/bold cyan]")
console.print(f"[bold white]engine_parameters:[/bold white]\n[dim cyan]{engine_info_str}[/dim cyan]")
console.print(f"[bold white]framework_parameters:[/bold white]\n[dim cyan]{framework_info_str}[/dim cyan]")
console.print(f"[bold white]extra_parameters:[/bold white]\n[dim cyan]{extra_params_info}[/dim cyan]")
# Start pipeline execution
if service_type != ServiceType.LOCAL:
response = sdk_deploy(
Expand All @@ -592,7 +596,7 @@ def deploy(
force_env_stack_update = force_update_env_stack,
waiting_until_deploy_complete=True
)
console.print(f"[bold green]Model deployment pipeline execution initiated. Execution ID: {response['pipeline_execution_id']}[/bold green]")
console.print(f"[bold green]Model deployment pipeline started. Execution ID: {response['pipeline_execution_id']}[/bold green]")
else:
response = sdk_deploy_local(
model_id=model_id,
Expand Down
48 changes: 44 additions & 4 deletions src/emd/commands/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,28 +28,45 @@ def status(
str, typer.Argument(help="Model tag")
] = MODEL_DEFAULT_TAG,
):
# Show loading indicator while fetching model status
with console.status("[bold green]Fetching model status...", spinner="dots"):
with console.status("[bold green]Fetching model deployment status. Please wait patiently", spinner="dots"):
ret = get_model_status(model_id, model_tag=model_tag)

inprogress = ret['inprogress']
completed = ret['completed']

data = []
# Process all in-progress executions (now includes ALL parallel executions)
cli_messages = [] # Store CLI messages for display after the table

# Process all in-progress executions (now includes enhanced pipeline-stack logic)
for d in inprogress:
if d['status'] == "Stopped":
continue

# Use enhanced status if available, otherwise fall back to original logic
if d.get('enhanced_status'):
display_status = d['enhanced_status']
else:
display_status = f"{d['status']} ({d['stage_name']})" if d.get('stage_name') else d['status']

data.append({
"model_id": d['model_id'],
"model_tag": d['model_tag'],
"status": f"{d['status']} ({d['stage_name']})" if d.get('stage_name') else d['status'],
"status": display_status,
"service_type": d.get('service_type', ''),
"instance_type": d.get('instance_type', ''),
"create_time": d.get('create_time', ''),
"outputs": d.get('outputs', ''), # Use .get() to handle missing outputs field
})

# Collect CLI messages for this model
if d.get('cli_message'):
model_name = f"{d['model_id']}/{d['model_tag']}"
cli_messages.append({
'model_name': model_name,
'message_type': d['cli_message'],
'stack_name': d.get('stack_name', '')
})

# Process completed models
for d in completed:
data.append({
Expand Down Expand Up @@ -152,6 +169,29 @@ def status(
# Display the table
console.print(models_table)

# Display CLI messages for user guidance
if cli_messages:
console.print("\n" + "=" * 60, style="dim")
console.print("📋 Action Required", style="bold yellow")
console.print("=" * 60, style="dim")

for msg in cli_messages:
model_name = msg['model_name']
message_type = msg['message_type']

if message_type == 'cleanup_warning':
stack_name = msg['stack_name']
console.print(f"\n🔧 [bold]{model_name}[/bold]")
console.print(" [yellow]⚠️ Failed stack detected. Manual cleanup required:[/yellow]")
console.print(f" [dim]aws cloudformation delete-stack --stack-name {stack_name}[/dim]")

elif message_type == 'codepipeline_console':
console.print(f"\n🔍 [bold]{model_name}[/bold]")
console.print(" [blue]💡 Check CodePipeline console for detailed logs:[/blue]")
console.print(" [dim]AWS Console → CodePipeline → EMD-Env-Pipeline[/dim]")

console.print()

# Display the Base URL section after the Models
console.print("\nBase URL", style="bold")
if base_url:
Expand Down
Binary file modified src/emd/sample/vlm_sample_data.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 8 additions & 10 deletions src/emd/sdk/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@
logger = get_logger(__name__)


def get_version_md5_value():
version_md5_value = calculate_md5_string(
f"{VERSION}-{get_account_id()}"
)[:8]
return version_md5_value
# def get_version_md5_value():
# version_md5_value = calculate_md5_string(
# f"{VERSION}-{get_account_id()}"
# )[:8]
# return version_md5_value


def get_bucket_name(
Expand All @@ -44,8 +44,8 @@ def get_bucket_name(
get bucket name
"""
assert region is not None,region
version_md5_value = get_version_md5_value()
bucket_name = f"{bucket_prefix}-{version_md5_value}-{region}"
# version_md5_value = get_version_md5_value()
bucket_name = f"{bucket_prefix}-{get_account_id()}-{region}"
return bucket_name


Expand Down Expand Up @@ -74,7 +74,6 @@ def create_env_stack(
if check_stack_exist_and_complete(stack_name) and not force_update:
logger.info(f"env stack: {stack_name} exists...")
return
logger.info(f"create env stack: {stack_name}...")
# version_md5_value = get_version_md5_value()
if bucket_name is None:
bucket_name = get_bucket_name(
Expand All @@ -92,7 +91,6 @@ def create_env_stack(
# logger.info(f'pipeline s3 path: {pipeline_s3_path}')

# create env stack
logger.info('create env stack...')
cloudformation = boto3.client('cloudformation', region_name=region)
cfn_template_path = os.path.join(emd_package_dir, "cfn", "codepipeline", "template.yaml")
with open(cfn_template_path, 'r') as f:
Expand Down Expand Up @@ -152,7 +150,7 @@ def create_stack():

# Track stack events during creation
# stack_id = response['StackId']
logger.info(f"monitor stack: {stack_name}")
logger.info(f"Monitoring deployment stack {stack_name}")
monitor_stack(stack_name)

def bootstrap():
Expand Down
Loading