A Streamlit application that generates AI-powered summaries of video content using Nvidia's Cosmos-reason2-8b vision-language model.

git clone <repo-url>
cd Nvidia_COSMOS
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
These files are excluded from the repository via .gitignore and must be created manually after cloning.
.envCreate a .env file in the project root:
SUPABASE_DB_URL=postgresql://<user>:<password>@<host>:5432/<dbname>?sslmode=require
LOGIN_USERNAME=your_username
LOGIN_PASSWORD=your_password
SUPABASE_DB_URL β your Supabase (or any PostgreSQL) connection stringLOGIN_USERNAME / LOGIN_PASSWORD β credentials for the app login screen.streamlit/secrets.tomlCreate the .streamlit/ directory and a secrets.toml file inside it:
mkdir .streamlit
Then create .streamlit/secrets.toml with the following content:
[passwords]
your_username = "your_password"
Add one line per user you want to allow. The username and password here must match what you set in .env (or you can use only one of the two approaches β both work).
Note: If VSCode shows these files greyed out, that is expected β they are gitignored to keep secrets out of version control. The files still work normally.
Make sure you have access to Nvidia's Cosmos-reason2-8b model. You may need to:
huggingface-cli loginmodel_handler.pyFor best performance, ensure you have:
To verify GPU availability:
import torch
print(torch.cuda.is_available())
This repo includes shell scripts for running the app on an NVIDIA Brev cloud GPU (for example H100) and opening Streamlit from your laptop via port forwarding.
In the Brev UI or CLI, create or open a deployment and note its name (for example cosmos-videos-gpu). You will use this name with brev shell, brev port-forward, and in portforward.sh (see below).
On your local machine, authenticate with Brev and SSH into the instance (run these from a regular terminal, not inside the instance yet):
brev login
brev shell <gpu-instance-name>
Replace <gpu-instance-name> with your deployment name from step 1. After this, your terminal session is on the Brev GPU machineβclone or cd into this repo there before the next steps.
Once in the GPU instance terminal run:
git clone <url>
cd Nvidia_COSMOS
ls
From the project root on the Brev instance:
python3 -m venv venv
source venv/bin/activate # Linux / macOS on the instance
Leave this shell active for the following steps so pip and python use the venv. (setup.sh in step 5 also creates or refreshes venv/ and activates it for installs.)
env.sh on the instance (not committed)env.sh is listed in .gitignore and is not pushed to the repo. On the Brev machine, from the project root, create the file with nano and paste your real credentials:
nano env.sh
In the editor, add export lines (same values you would use in .env, plus a HuggingFace token if you use one). For example:
export HUGGINGFACE_HUB_TOKEN="hf_..." # optional if you use huggingface-cli login instead
export SUPABASE_DB_URL="postgresql://..."
export LOGIN_USERNAME="..."
export LOGIN_PASSWORD="..."
Save and exit: Ctrl+O, Enter, then Ctrl+X.
run.sh sources this file before starting the app.
ensure your on the directory: Nvidia_COSMOS
chmod +x setup.sh run.sh
bash setup.sh
setup.sh updates packages, installs python3.10-venv, creates venv/, upgrades pip, installs requirements.txt, and adds Streamlit / torchvision / accelerate / huggingface_hub, plus a pinned jinja2 version.
bash run.sh
run.sh sources env.sh, runs setup.sh again, then starts Streamlit with:
python3 -m streamlit run app.py --server.port 8501 --server.address 0.0.0.0
so the service is reachable through port forwarding.
On your local machine (where the Brev CLI is installed), forward remote port 8501 to local 8501:
brev port-forward <your-deployment-name> -p 8501:8501
Replace <your-deployment-name> with your actual Brev deployment name.
On macOS, portforward.sh opens a new Terminal window and runs a brev port-forward command for you. Edit the deployment name inside that script to match yours, then:
chmod +x portforward.sh
./portforward.sh
Visit http://localhost:8501 on your laptop while the port forward is active.
streamlit run app.py
python3 -m streamlit run app.py
The application will open in your default web browser at http://localhost:8501
Configure Settings (in sidebar):
Upload Video:
Generate Summary:
Review Results:
Tracked files only (see .gitignore for excluded paths like .env, .idea/, venv/).
Nvidia_COSMOS/
βββ app.py # Main Streamlit application
βββ video_processor.py # Frame extraction and video processing
βββ model_handler.py # Cosmos model interface
βββ summarizer.py # Summary generation logic
βββ test_setup.py # Verify setup (imports, GPU, video processor)
βββ db/
β βββ connection.py # PostgreSQL connection (SUPABASE_DB_URL)
β βββ video_store.py # Insert video summaries with embeddings
β βββ search_video.py # Similarity search over summaries
βββ embeddings/
β βββ embedder.py # Text β 384-dim vector (sentence-transformers)
β βββ init.py
βββ requirements.txt
βββ README.md
βββ QUICKSTART.md
The app can store video summaries in PostgreSQL with the pgvector extension for similarity search.
In Supabase, make sure the vector extension is enabled and you have a video_summaries table with an embedding column of dimension 384 (matches all-MiniLM-L6-v2).
CREATE EXTENSION IF NOT EXISTS vector;video_summaries| Column | Type | Description |
|---|---|---|
id | BIGSERIAL | Primary key |
created_at | TIMESTAMPTZ | Default NOW() |
filename | TEXT | Original video filename (optional) |
duration_sec | NUMERIC(10,2) | Video duration in seconds (optional) |
summary_style | TEXT | e.g. "detailed", "concise" |
summary_text | TEXT NOT NULL | Full summary text |
embedding | vector(384) | Embedding for similarity search (all-MiniLM-L6-v2) |
Optional index for faster search once you have many rows:
CREATE INDEX ON video_summaries
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
The VideoProcessor class provides two methods:
Interval-based extraction (default):
Keyframe extraction:
app.py to call extract_keyframes() instead of extract_frames()In model_handler.py, you can adjust:
model_name: HuggingFace model ID or local pathmax_new_tokens: Maximum length of generated descriptionstemperature: Creativity of responses (0.0-1.0)batch_size: Number of frames to process togetherYou can modify or add new summary styles in summarizer.py:
_generate_detailed_summary(): Narrative format with scenes_generate_concise_summary(): Brief overview with key moments_generate_bullet_summary(): Point-by-point breakdownCustomize the prompts sent to the Cosmos model in model_handler.py:
prompt parameter in analyze_single_frame()analyze_with_context()Login fails / "no credentials found"
.env exists in the project root with LOGIN_USERNAME and LOGIN_PASSWORD set.streamlit/secrets.toml exists with a [passwords] sectionstreamlit run app.py from the project root β Streamlit looks for .streamlit/secrets.toml relative to the working directoryTest-Path ".streamlit\secrets.toml" should return True"Missing SUPABASE_DB_URL"
.env exists and contains SUPABASE_DB_URL=...python-dotenv package must be installed (pip install -r requirements.txt)"Could not open video file"
"CUDA out of memory"
max_frames in the sidebarframe_interval to sample fewer frames"Model not found"
model_handler.py is correctSlow processing
Potential improvements:
This project is provided as-is for educational and research purposes.
For issues or questions:
Python
98.4%
Shell
1.6%
A Streamlit application that generates AI-powered summaries of video content using Nvidia's Cosmos-reason2-8b vision-language model.

git clone <repo-url>
cd Nvidia_COSMOS
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -r requirements.txt
These files are excluded from the repository via .gitignore and must be created manually after cloning.
.envCreate a .env file in the project root:
SUPABASE_DB_URL=postgresql://<user>:<password>@<host>:5432/<dbname>?sslmode=require
LOGIN_USERNAME=your_username
LOGIN_PASSWORD=your_password
SUPABASE_DB_URL β your Supabase (or any PostgreSQL) connection stringLOGIN_USERNAME / LOGIN_PASSWORD β credentials for the app login screen.streamlit/secrets.tomlCreate the .streamlit/ directory and a secrets.toml file inside it:
mkdir .streamlit
Then create .streamlit/secrets.toml with the following content:
[passwords]
your_username = "your_password"
Add one line per user you want to allow. The username and password here must match what you set in .env (or you can use only one of the two approaches β both work).
Note: If VSCode shows these files greyed out, that is expected β they are gitignored to keep secrets out of version control. The files still work normally.
Make sure you have access to Nvidia's Cosmos-reason2-8b model. You may need to:
huggingface-cli loginmodel_handler.pyFor best performance, ensure you have:
To verify GPU availability:
import torch
print(torch.cuda.is_available())
This repo includes shell scripts for running the app on an NVIDIA Brev cloud GPU (for example H100) and opening Streamlit from your laptop via port forwarding.
In the Brev UI or CLI, create or open a deployment and note its name (for example cosmos-videos-gpu). You will use this name with brev shell, brev port-forward, and in portforward.sh (see below).
On your local machine, authenticate with Brev and SSH into the instance (run these from a regular terminal, not inside the instance yet):
brev login
brev shell <gpu-instance-name>
Replace <gpu-instance-name> with your deployment name from step 1. After this, your terminal session is on the Brev GPU machineβclone or cd into this repo there before the next steps.
Once in the GPU instance terminal run:
git clone <url>
cd Nvidia_COSMOS
ls
From the project root on the Brev instance:
python3 -m venv venv
source venv/bin/activate # Linux / macOS on the instance
Leave this shell active for the following steps so pip and python use the venv. (setup.sh in step 5 also creates or refreshes venv/ and activates it for installs.)
env.sh on the instance (not committed)env.sh is listed in .gitignore and is not pushed to the repo. On the Brev machine, from the project root, create the file with nano and paste your real credentials:
nano env.sh
In the editor, add export lines (same values you would use in .env, plus a HuggingFace token if you use one). For example:
export HUGGINGFACE_HUB_TOKEN="hf_..." # optional if you use huggingface-cli login instead
export SUPABASE_DB_URL="postgresql://..."
export LOGIN_USERNAME="..."
export LOGIN_PASSWORD="..."
Save and exit: Ctrl+O, Enter, then Ctrl+X.
run.sh sources this file before starting the app.
ensure your on the directory: Nvidia_COSMOS
chmod +x setup.sh run.sh
bash setup.sh
setup.sh updates packages, installs python3.10-venv, creates venv/, upgrades pip, installs requirements.txt, and adds Streamlit / torchvision / accelerate / huggingface_hub, plus a pinned jinja2 version.
bash run.sh
run.sh sources env.sh, runs setup.sh again, then starts Streamlit with:
python3 -m streamlit run app.py --server.port 8501 --server.address 0.0.0.0
so the service is reachable through port forwarding.
On your local machine (where the Brev CLI is installed), forward remote port 8501 to local 8501:
brev port-forward <your-deployment-name> -p 8501:8501
Replace <your-deployment-name> with your actual Brev deployment name.
On macOS, portforward.sh opens a new Terminal window and runs a brev port-forward command for you. Edit the deployment name inside that script to match yours, then:
chmod +x portforward.sh
./portforward.sh
Visit http://localhost:8501 on your laptop while the port forward is active.
streamlit run app.py
python3 -m streamlit run app.py
The application will open in your default web browser at http://localhost:8501
Configure Settings (in sidebar):
Upload Video:
Generate Summary:
Review Results:
Tracked files only (see .gitignore for excluded paths like .env, .idea/, venv/).
Nvidia_COSMOS/
βββ app.py # Main Streamlit application
βββ video_processor.py # Frame extraction and video processing
βββ model_handler.py # Cosmos model interface
βββ summarizer.py # Summary generation logic
βββ test_setup.py # Verify setup (imports, GPU, video processor)
βββ db/
β βββ connection.py # PostgreSQL connection (SUPABASE_DB_URL)
β βββ video_store.py # Insert video summaries with embeddings
β βββ search_video.py # Similarity search over summaries
βββ embeddings/
β βββ embedder.py # Text β 384-dim vector (sentence-transformers)
β βββ init.py
βββ requirements.txt
βββ README.md
βββ QUICKSTART.md
The app can store video summaries in PostgreSQL with the pgvector extension for similarity search.
In Supabase, make sure the vector extension is enabled and you have a video_summaries table with an embedding column of dimension 384 (matches all-MiniLM-L6-v2).
CREATE EXTENSION IF NOT EXISTS vector;video_summaries| Column | Type | Description |
|---|---|---|
id | BIGSERIAL | Primary key |
created_at | TIMESTAMPTZ | Default NOW() |
filename | TEXT | Original video filename (optional) |
duration_sec | NUMERIC(10,2) | Video duration in seconds (optional) |
summary_style | TEXT | e.g. "detailed", "concise" |
summary_text | TEXT NOT NULL | Full summary text |
embedding | vector(384) | Embedding for similarity search (all-MiniLM-L6-v2) |
Optional index for faster search once you have many rows:
CREATE INDEX ON video_summaries
USING ivfflat (embedding vector_cosine_ops)
WITH (lists = 100);
The VideoProcessor class provides two methods:
Interval-based extraction (default):
Keyframe extraction:
app.py to call extract_keyframes() instead of extract_frames()In model_handler.py, you can adjust:
model_name: HuggingFace model ID or local pathmax_new_tokens: Maximum length of generated descriptionstemperature: Creativity of responses (0.0-1.0)batch_size: Number of frames to process togetherYou can modify or add new summary styles in summarizer.py:
_generate_detailed_summary(): Narrative format with scenes_generate_concise_summary(): Brief overview with key moments_generate_bullet_summary(): Point-by-point breakdownCustomize the prompts sent to the Cosmos model in model_handler.py:
prompt parameter in analyze_single_frame()analyze_with_context()Login fails / "no credentials found"
.env exists in the project root with LOGIN_USERNAME and LOGIN_PASSWORD set.streamlit/secrets.toml exists with a [passwords] sectionstreamlit run app.py from the project root β Streamlit looks for .streamlit/secrets.toml relative to the working directoryTest-Path ".streamlit\secrets.toml" should return True"Missing SUPABASE_DB_URL"
.env exists and contains SUPABASE_DB_URL=...python-dotenv package must be installed (pip install -r requirements.txt)"Could not open video file"
"CUDA out of memory"
max_frames in the sidebarframe_interval to sample fewer frames"Model not found"
model_handler.py is correctSlow processing
Potential improvements:
This project is provided as-is for educational and research purposes.
For issues or questions:
Python
98.4%
Shell
1.6%