Skip to content

Latest commit

 

History

History
169 lines (114 loc) · 8.29 KB

File metadata and controls

169 lines (114 loc) · 8.29 KB

Nearby Mood Map

Nearby Mood Map turns a user's mood and location into nearby place and event recommendations, then displays them on an interactive Three.js map. Each live result receives a clearly labeled PixArt-Sigma representative image generated on an AMD ROCm GPU; it is not presented as a factual photograph of the venue or event.

The application is designed for the Radeon Cloud ROCm environment. PixArt inference deliberately refuses to fall back to CPU or any other non-ROCm GPU runtime, so a successful end-to-end image-generation run is an AMD ROCm run.

What is included

Path Purpose
api.py FastAPI server, background recommendation jobs, health endpoint, and benchmark endpoint
discovery.py Geoapify Places, Ticketmaster, and static-map integration
pixart.py ROCm-only PixArt-Sigma loading and image generation
benchmark_pixart.py Reproducible, synchronized PyTorch latency and memory benchmark
threejs-poi-map-demo/ Interactive browser map and an offline-safe initial map demo
artifacts/ Runtime benchmark reports; generated reports are ignored by Git
.env.example Required API-key configuration template

There is no Map3D pipeline, database, Node.js install, or Docker dependency in this repository.

Requirements

Radeon Cloud target

  • A Radeon Cloud notebook/instance with an AMD GPU, ROCm 7.2.1, 64-bit Linux, and CPython 3.12.
  • Internet access to download the PixArt model on first use and to call Geoapify and Ticketmaster.
  • A Geoapify API key and a Ticketmaster API key.

The AMD ROCm PyTorch, TorchVision, TorchAudio, and Triton wheels in requirements.txt target precisely this Linux/Python combination. The host image must provide the AMD driver and device access; installing a Python wheel cannot add those host capabilities.

Python dependencies

requirements.txt is the complete direct Python dependency list:

  • ROCm runtime: PyTorch, TorchVision, TorchAudio, and Triton
  • API: FastAPI, Uvicorn, Pydantic, Requests, and Windows tzdata support
  • PixArt: Diffusers, Transformers, Accelerate, Safetensors, SentencePiece, ftfy, Beautiful Soup, and Pillow

Pip installs their transitive dependencies automatically. No packages need to be installed manually after the requirements command succeeds.

Fresh Radeon Cloud setup

Create a Radeon Cloud notebook from the ROCm 7.2.1 / Python 3.12 template. In its Jupyter terminal, clone or open this repository and run all Python commands through /opt/venv/bin/python. Do not create a second virtual environment or mix in bare pip3, python, or uvicorn commands.

git clone <your-submission-repository-url> nearby-mood-map
cd nearby-mood-map

cp .env.example .env
nano .env

Set both values in .env:

GEOAPIFY_API_KEY=your_geoapify_key
TICKETMASTER_API_KEY=your_ticketmaster_key

Install the application and ROCm wheels. This is needed once per fresh environment, not after every code change.

/opt/venv/bin/python -m pip install --no-cache-dir -r requirements.txt

Before loading the model, confirm that this same interpreter can see ROCm and Diffusers:

rocm-smi

/opt/venv/bin/python - <<'PY'
import diffusers
import torch

print("PyTorch:", torch.__version__)
print("ROCm/HIP:", torch.version.hip)
print("GPU available:", torch.cuda.is_available())
print("Diffusers:", diffusers.__version__)
PY

GPU available must be True and ROCm/HIP must have a version. rocm-smi by itself only proves that the host sees the GPU; the Python check proves that the application interpreter has the right PyTorch build.

Start the server

In the first Jupyter terminal:

/opt/venv/bin/python -m uvicorn api:app --host 127.0.0.1 --port 8000

The 127.0.0.1 binding is intentional: Radeon Cloud's HTTP tunnel connects to that loopback address. Verify the service from the same terminal or a second terminal:

curl --fail http://127.0.0.1:8000/api/health

The JSON response should show both API keys as configured and pixart.ready: true with pixart.rocm: true.

Open the application from your computer

In a second Jupyter terminal, install the Radeon Cloud tunnel tool once for a newly created notebook, then expose the already-running server:

/var/run/secrets/frp-self-service/install
"$HOME/.local/bin/rc-tunnel" expose --port 8000

The command prints a public https://... URL. Open that URL in your local browser; it redirects to /map/. This is an HTTP tunnel, not an SSH tunnel. Do not use the notebook's internal IP address, 0.0.0.0, or port 8000 directly from your computer.

After restarting only Uvicorn, the existing tunnel normally remains usable. Check it before creating another one:

"$HOME/.local/bin/rc-tunnel" status

The tunnel URL is public and the demo has no authentication, so share it only for testing and stop it when finished.

End-to-end test

  1. Open the tunnel URL and confirm that the offline demo map displays its three checked-in sample images.
  2. Choose a destination (or use browser geolocation), enter a mood, and select Find nearby places.
  3. The browser starts a background job, polls for progress, and reloads the map after discovery, PixArt generation, and ground-map creation finish.

The normal UI may request up to eight 1024×1024 images at 20 denoising steps, so this can take a few minutes and use substantial GPU memory even at FP16.

For a fast smoke test, open <tunnel-url>/docs, expand POST /api/recommendations, choose Try it out, and submit one result and one short generation:

{
  "mood": "I need a boost in energy",
  "latitude": 34.4208,
  "longitude": -119.6982,
  "radius_m": 3000,
  "max_results": 1,
  "image_limit": 1,
  "inference_steps": 4,
  "guidance_scale": 4.5,
  "seed": 42,
  "timezone_name": "America/Los_Angeles"
}

The response returns a job_id. Use GET /api/recommendations/{job_id} in the same API page until its status is done, then open the returned map_url. A live request overwrites threejs-poi-map-demo/config.js, writes generated images under threejs-poi-map-demo/images/, and may write ground-map.png; those live image files are intentionally ignored by Git.

Benchmark PixArt on the AMD GPU

Do not run the benchmark concurrently with an interactive recommendation job. On the Radeon Cloud terminal, with the GPU otherwise idle:

/opt/venv/bin/python benchmark_pixart.py --warmups 1 --runs 5 --steps 20

The command prints a JSON report and writes it to artifacts/benchmarks/pixart-rocm.json. The report includes the loaded parameter count, ROCm/PyTorch and GPU information, pipeline-load time, synchronized latency samples, p50/p95/mean latency, throughput, peak memory, and a rocm-smi snapshot. Benchmark reports are intentionally untracked so repeated runs do not dirty the submission repository.

Alternatively, the running API exposes POST /api/benchmarks/pixart; it returns the report and saves a timestamped JSON file under artifacts/benchmarks/.

Precision note

pixart.py loads PixArt-Sigma in torch.float16, matching the PixArt-Sigma model card. The Radeon Cloud image's preinstalled Apex previously caused an expected scalar type Float but found Half failure by auto-swapping in a fused T5 normalization kernel that assumes float32; pixart.py now blocks that Apex patch before transformers loads (see Radeon Cloud operations notes) so the pipeline can run FP16 without it.

Troubleshooting

  • diffusers is not installed: packages were installed into a different interpreter. Re-run the requirements command and Uvicorn command using /opt/venv/bin/python.
  • GPU available: False or ROCm/HIP: None: the Python environment does not have the matching ROCm PyTorch wheel, even if rocm-smi works.
  • Tunnel does not open: confirm /api/health succeeds locally, confirm Uvicorn is bound to 127.0.0.1:8000, then check rc-tunnel status rather than repeatedly creating new tunnels.
  • A local non-AMD computer can view the static map but cannot run PixArt inference or the submission benchmark. The server rejects non-ROCm image generation by design.

See Radeon Cloud operations notes for the cloud-specific details. PixArt-Sigma is distributed under the CreativeML Open RAIL++-M license.