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:
| Good | Bad |
|---|---|
image_classifier | ImageClassifier |
text_summarizer | my-model-v2 |
sd3_turbo | test |
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
| Symptom | Likely cause | Fix |
|---|---|---|
ModuleNotFoundError | Missing entry in requirements | Add the package with a pinned version |
| Deployment timeout | Too many or too large dependencies | Minimize requirements, use pre-installed packages |
metadata.yaml errors | Extra directories in project root | Remove all folders except the model directory |
| Logs not available | Model started successfully | No action needed — logs are captured on failure |
| 4xx error on deploy | Model already exists | Run fma update instead of fma deploy |