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