Skip to main content

Best Practices

Recommendations for working effectively with the FlyMyAI CLI.

Project structure​

Keep the project directory clean​

The project root must contain only your model folder and metadata.yaml. Any extra directories will cause a deployment error.

my_model/
└── model.py
metadata.yaml

Do not place virtual environments, notebooks, data files, or other folders alongside the model directory.

Use descriptive model names​

Model names become part of your deployment identifier. Use lowercase with underscores:

GoodBad
image_classifierImageClassifier
text_summarizermy-model-v2
sd3_turbotest

Model development​

Put imports inside methods​

All imports except pydantic, typing, and fma.toolkit must go inside initialize() and predict(). This ensures dependencies are resolved at runtime on the target infrastructure.

class Model(fma_model.Model):
requirements: List[str] = ["transformers==4.45.2"]

def initialize(self):
from transformers import pipeline
self.pipe = pipeline("sentiment-analysis")

def predict(self, input: Input) -> Output:
result = self.pipe(input["text"])
return {"label": result[0]["label"]}

Load heavy resources in initialize(), not predict()​

Model weights, pipelines, and tokenizers should be loaded once in initialize() and stored on self. The predict() method runs per-request and should be as fast as possible.

# Bad - loads the model on every request
def predict(self, input: Input) -> Output:
from transformers import pipeline
pipe = pipeline("sentiment-analysis") # slow!
return {"label": pipe(input["text"])[0]["label"]}

# Good - loaded once, reused across requests
def initialize(self):
from transformers import pipeline
self.pipe = pipeline("sentiment-analysis")

def predict(self, input: Input) -> Output:
return {"label": self.pipe(input["text"])[0]["label"]}

Handle optional inputs with .get()​

Since predict() receives plain Python dicts (not Pydantic model instances), use .get() with defaults for optional fields:

def predict(self, input: Input) -> Output:
prompt = input["prompt"] # required
width = input.get("width", 1024) # optional with default
height = input.get("height", 1024) # optional with default
steps = input.get("num_inference_steps", 4) # optional with default
# ...

Dependency management​

Pin exact versions​

Always specify exact versions in the requirements list. Unpinned dependencies can break between deployments.

# Good
requirements: List[str] = [
"diffusers==0.30.0",
"Pillow==10.4.0",
"protobuf==5.28.0",
]

# Bad - may install incompatible versions
requirements: List[str] = [
"diffusers",
"Pillow",
"protobuf",
]

Respect pre-installed package versions​

The infrastructure provides specific versions of common ML libraries (see Supported packages). Requesting conflicting versions will cause installation failures. If you need torch, do not add it to requirements - it is already available.

Keep requirements minimal​

Only list packages that are not pre-installed. Redundant entries increase deployment time without benefit.

Authentication and security​

Never hardcode secrets in model code​

Use environment variables set inside initialize() rather than committing tokens to source control:

def initialize(self):
import os
os.environ["HF_TOKEN"] = "<set-at-runtime>"
# ...

If your model needs API keys or tokens, consider using metadata.yaml or environment-based configuration rather than hardcoding values in model.py.

Prefer interactive login​

Avoid passing --password directly on the command line, as it may be saved in shell history:

# Preferred - password is prompted securely
fma login

# Acceptable for CI/CD
fma login --username "$FMA_USER" --password "$FMA_PASS"

Deployment workflow​

Check logs after every deployment​

Run fma logs immediately after fma deploy to verify that the model initialized correctly. Startup logs are most useful when something fails silently:

fma deploy
fma logs

Save logs to a file for sharing with your team or for later review:

fma logs --output-file startup_logs.txt

Use fma update for iterative development​

Instead of manually running fma delete followed by fma deploy, use fma update which handles both steps:

# Edit model.py...
fma update

Test locally before deploying​

Before deploying, verify that your model loads and runs locally:

from my_model.model import Model, Input

m = Model()
m.initialize()

sample_input = {"prompt": "a cat sitting on a cloud"}
result = m.predict(sample_input)
print(result)

This catches import errors, missing dependencies, and logic issues without waiting for remote builds.

Debugging​

Enable debug mode​

Use the --debug flag for verbose output during any CLI operation:

fma --debug deploy
fma --debug logs

This reveals HTTP request details, API responses, and detailed error traces.

Common failure patterns​

SymptomLikely causeFix
ModuleNotFoundErrorMissing entry in requirementsAdd the package with a pinned version
Deployment timeoutToo many or too large dependenciesMinimize requirements, use pre-installed packages
metadata.yaml errorsExtra directories in project rootRemove all folders except the model directory
Logs not availableModel started successfullyNo action needed - logs are captured on failure
4xx error on deployModel already existsRun fma update instead of fma deploy