kingkulk commited on
Commit
e6ee420
·
verified ·
1 Parent(s): b511fde

Upload 5 files

Browse files
Files changed (5) hide show
  1. Dockerfile +25 -0
  2. README.md +93 -10
  3. SETUP_INSTRUCTIONS.md +144 -0
  4. app.py +196 -0
  5. requirements.txt +8 -0
Dockerfile ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.10-slim
2
+
3
+ # Install system dependencies
4
+ RUN apt-get update && apt-get install -y \
5
+ build-essential \
6
+ && rm -rf /var/lib/apt/lists/*
7
+
8
+ # Set working directory
9
+ WORKDIR /app
10
+
11
+ # Copy requirements
12
+ COPY requirements.txt .
13
+
14
+ # Install Python dependencies
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Copy application
18
+ COPY app.py .
19
+
20
+ # Expose port
21
+ EXPOSE 7860
22
+
23
+ # Run application
24
+ CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "7860"]
25
+
README.md CHANGED
@@ -1,10 +1,93 @@
1
- ---
2
- title: Plasmidgpt
3
- emoji: 🦀
4
- colorFrom: yellow
5
- colorTo: gray
6
- sdk: docker
7
- pinned: false
8
- ---
9
-
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: PlasmidGPT API
3
+ emoji: 🧬
4
+ colorFrom: blue
5
+ colorTo: green
6
+ sdk: docker
7
+ sdk_version: 4.0.0
8
+ app_file: Dockerfile
9
+ pinned: false
10
+ license: cc-by-nc-4.0
11
+ ---
12
+
13
+ # PlasmidGPT API Service
14
+
15
+ This HuggingFace Space deploys the PlasmidGPT model as a FastAPI service for DNA sequence generation.
16
+
17
+ ## Features
18
+
19
+ - 🧬 DNA sequence generation using PlasmidGPT
20
+ - 🚀 FastAPI REST API
21
+ - 💻 GPU acceleration (free on HuggingFace)
22
+ - 🔒 CORS enabled for external API calls
23
+
24
+ ## API Endpoints
25
+
26
+ ### Health Check
27
+ ```
28
+ GET /health
29
+ ```
30
+
31
+ ### Generate Sequences
32
+ ```
33
+ POST /generate
34
+ Content-Type: application/json
35
+
36
+ {
37
+ "prompt": "ATGAAA",
38
+ "max_length": 100,
39
+ "temperature": 0.7,
40
+ "num_return_sequences": 1,
41
+ "do_sample": true,
42
+ "repetition_penalty": 1.1
43
+ }
44
+ ```
45
+
46
+ ## Usage from Render Backend
47
+
48
+ Once deployed, your Render backend can call this Space:
49
+
50
+ ```python
51
+ import httpx
52
+
53
+ space_url = "https://your-username-plasmidgpt-api.hf.space"
54
+ response = await httpx.post(
55
+ f"{space_url}/generate",
56
+ json={
57
+ "prompt": "ATGAAA",
58
+ "max_length": 100,
59
+ "temperature": 0.7
60
+ }
61
+ )
62
+ ```
63
+
64
+ ## Setup Instructions
65
+
66
+ 1. **Create Space:**
67
+ - Go to https://huggingface.co/spaces
68
+ - Click "Create new Space"
69
+ - Name: `your-username/plasmidgpt-api`
70
+ - SDK: Docker
71
+ - Visibility: Public
72
+
73
+ 2. **Upload Files:**
74
+ - Upload `app.py`
75
+ - Upload `requirements.txt`
76
+ - Upload `Dockerfile` (if using Docker SDK)
77
+
78
+ 3. **Deploy:**
79
+ - Space will automatically build and deploy
80
+ - Wait for model to load (first time takes ~5-10 minutes)
81
+ - Check `/health` endpoint to verify
82
+
83
+ 4. **Get Space URL:**
84
+ - Your Space URL: `https://your-username-plasmidgpt-api.hf.space`
85
+ - Use this in your Render backend configuration
86
+
87
+ ## Notes
88
+
89
+ - First deployment takes longer (model download)
90
+ - Model uses GPU if available (free on HuggingFace)
91
+ - Space sleeps after inactivity (wake up on first request)
92
+ - CORS is enabled for external API calls
93
+
SETUP_INSTRUCTIONS.md ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # PlasmidGPT HuggingFace Space Setup Instructions
2
+
3
+ ## Quick Start
4
+
5
+ 1. **Create HuggingFace Space**
6
+ 2. **Upload Files**
7
+ 3. **Deploy**
8
+ 4. **Configure Render Backend**
9
+
10
+ ## Step-by-Step Guide
11
+
12
+ ### Step 1: Create HuggingFace Space
13
+
14
+ 1. Go to https://huggingface.co/spaces
15
+ 2. Click **"Create new Space"**
16
+ 3. Fill in:
17
+ - **Space name**: `your-username/plasmidgpt-api` (replace `your-username` with your HF username)
18
+ - **SDK**: Select **"Docker"**
19
+ - **Hardware**: Select **"GPU Basic"** (free tier)
20
+ - **Visibility**: **Public** (required for API access)
21
+ 4. Click **"Create Space"**
22
+
23
+ ### Step 2: Upload Files
24
+
25
+ In your new Space, upload these files from the `huggingface-space/` directory:
26
+
27
+ 1. **`app.py`** - Main FastAPI application
28
+ 2. **`requirements.txt`** - Python dependencies
29
+ 3. **`Dockerfile`** - Docker configuration
30
+ 4. **`README.md`** - Space documentation (optional)
31
+
32
+ **How to upload:**
33
+ - Click "Files and versions" tab
34
+ - Click "Add file" → "Upload files"
35
+ - Drag and drop the files
36
+ - Commit changes
37
+
38
+ ### Step 3: Wait for Deployment
39
+
40
+ 1. HuggingFace will automatically build and deploy your Space
41
+ 2. **First deployment takes 5-10 minutes** (model download)
42
+ 3. Watch the logs in the Space interface
43
+ 4. Look for: `✅ PlasmidGPT model loaded successfully!`
44
+
45
+ ### Step 4: Test Your Space
46
+
47
+ 1. Go to your Space URL: `https://your-username-plasmidgpt-api.hf.space`
48
+ 2. Test the health endpoint:
49
+ ```
50
+ https://your-username-plasmidgpt-api.hf.space/health
51
+ ```
52
+ 3. Should return:
53
+ ```json
54
+ {
55
+ "status": "healthy",
56
+ "model_loaded": true,
57
+ "device": "cuda",
58
+ "model_name": "lingxusb/PlasmidGPT"
59
+ }
60
+ ```
61
+
62
+ ### Step 5: Configure Render Backend
63
+
64
+ 1. **Get your Space URL:**
65
+ - Format: `https://your-username-plasmidgpt-api.hf.space`
66
+ - No trailing slash!
67
+
68
+ 2. **Update `render.yaml`:**
69
+ ```yaml
70
+ envVars:
71
+ - key: PLASMIDGPT_ENABLED
72
+ value: "true"
73
+ - key: PLASMIDGPT_SPACE_URL
74
+ value: "https://your-username-plasmidgpt-api.hf.space"
75
+ ```
76
+
77
+ 3. **Or set environment variable in Render dashboard:**
78
+ - Go to your Render service
79
+ - Environment tab
80
+ - Add: `PLASMIDGPT_SPACE_URL` = `https://your-username-plasmidgpt-api.hf.space`
81
+
82
+ 4. **Redeploy your Render service**
83
+
84
+ ### Step 6: Verify Integration
85
+
86
+ 1. **Check backend logs:**
87
+ ```
88
+ INFO: HuggingFace client initialized for custom Space: https://your-username-plasmidgpt-api.hf.space
89
+ ```
90
+
91
+ 2. **Test health endpoint:**
92
+ ```bash
93
+ curl https://your-render-app.onrender.com/api/plasmidgpt/health
94
+ ```
95
+ Should return: `"status": "healthy"`
96
+
97
+ 3. **Test sequence generation:**
98
+ - Ask your design agent: "Generate a plasmid for protein expression"
99
+ - Should see: "🤖 Using LLM to generate optimized prompt for PlasmidGPT..."
100
+ - Then: "🧬 Starting AI-powered DNA sequence generation..."
101
+
102
+ ## Troubleshooting
103
+
104
+ ### Space won't deploy
105
+ - Check Dockerfile syntax
106
+ - Verify all files are uploaded
107
+ - Check Space logs for errors
108
+
109
+ ### Model loading fails
110
+ - Ensure GPU is selected (not CPU)
111
+ - Check if model name is correct: `lingxusb/PlasmidGPT`
112
+ - Verify you have enough disk space
113
+
114
+ ### Space sleeps after inactivity
115
+ - This is normal! First request after sleep takes ~30 seconds
116
+ - Space wakes up automatically on first API call
117
+ - Consider upgrading to "GPU Basic" (still free) for faster wake-up
118
+
119
+ ### Backend can't connect
120
+ - Verify Space URL is correct (no trailing slash)
121
+ - Check CORS settings in `app.py` (should allow your Render domain)
122
+ - Test Space health endpoint directly in browser
123
+
124
+ ### Generation fails
125
+ - Check Space logs for errors
126
+ - Verify model is loaded: `/health` endpoint
127
+ - Test generation directly: `POST /generate` with test payload
128
+
129
+ ## Cost
130
+
131
+ - **HuggingFace Space**: Free (GPU Basic tier)
132
+ - **Render Backend**: Your existing plan (no changes needed)
133
+ - **Total**: $0 additional cost! 🎉
134
+
135
+ ## Next Steps
136
+
137
+ Once deployed:
138
+ - ✅ PlasmidGPT is fully functional
139
+ - ✅ Hybrid LLM integration works
140
+ - ✅ Sequence generation available
141
+ - ✅ No PyTorch needed on Render
142
+
143
+ Enjoy your AI-powered plasmid design! 🧬
144
+
app.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ PlasmidGPT HuggingFace Space Deployment
3
+
4
+ This Space loads the PlasmidGPT model and exposes it as a FastAPI service
5
+ that can be called from your Render backend.
6
+ """
7
+
8
+ import os
9
+ import logging
10
+ from typing import Dict, Any, Optional
11
+ from fastapi import FastAPI, HTTPException
12
+ from fastapi.middleware.cors import CORSMiddleware
13
+ from pydantic import BaseModel, Field
14
+ import torch
15
+ from transformers import AutoModelForCausalLM, AutoTokenizer
16
+ import time
17
+
18
+ # Configure logging
19
+ logging.basicConfig(level=logging.INFO)
20
+ logger = logging.getLogger(__name__)
21
+
22
+ # Initialize FastAPI app
23
+ app = FastAPI(
24
+ title="PlasmidGPT API",
25
+ description="PlasmidGPT model API for DNA sequence generation",
26
+ version="1.0.0"
27
+ )
28
+
29
+ # Enable CORS for Render backend
30
+ app.add_middleware(
31
+ CORSMiddleware,
32
+ allow_origins=["*"], # In production, restrict to your Render URL
33
+ allow_credentials=True,
34
+ allow_methods=["*"],
35
+ allow_headers=["*"],
36
+ )
37
+
38
+ # Global model and tokenizer
39
+ model = None
40
+ tokenizer = None
41
+ device = "cuda" if torch.cuda.is_available() else "cpu"
42
+
43
+ # Request/Response models
44
+ class GenerationRequest(BaseModel):
45
+ prompt: str = Field(..., description="DNA sequence prompt or seed")
46
+ max_length: int = Field(100, ge=10, le=1000, description="Maximum sequence length")
47
+ temperature: float = Field(0.7, ge=0.0, le=2.0, description="Sampling temperature")
48
+ num_return_sequences: int = Field(1, ge=1, le=3, description="Number of sequences to generate")
49
+ do_sample: bool = Field(True, description="Whether to use sampling")
50
+ repetition_penalty: float = Field(1.1, ge=1.0, le=2.0, description="Repetition penalty")
51
+
52
+ class GenerationResponse(BaseModel):
53
+ sequences: list[str]
54
+ metadata: Dict[str, Any]
55
+ generation_time: float
56
+
57
+ class HealthResponse(BaseModel):
58
+ status: str
59
+ model_loaded: bool
60
+ device: str
61
+ model_name: str
62
+
63
+ @app.on_event("startup")
64
+ async def load_model():
65
+ """Load PlasmidGPT model on startup."""
66
+ global model, tokenizer
67
+
68
+ logger.info("Loading PlasmidGPT model...")
69
+ logger.info(f"Using device: {device}")
70
+
71
+ try:
72
+ model_name = "lingxusb/PlasmidGPT"
73
+
74
+ # Load tokenizer
75
+ logger.info("Loading tokenizer...")
76
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
77
+
78
+ # Load model
79
+ logger.info("Loading model (this may take a few minutes)...")
80
+ model = AutoModelForCausalLM.from_pretrained(
81
+ model_name,
82
+ torch_dtype=torch.float16 if device == "cuda" else torch.float32,
83
+ device_map="auto" if device == "cuda" else None
84
+ )
85
+
86
+ if device == "cpu":
87
+ model = model.to(device)
88
+
89
+ model.eval()
90
+
91
+ logger.info("✅ PlasmidGPT model loaded successfully!")
92
+ logger.info(f"Model device: {next(model.parameters()).device}")
93
+
94
+ except Exception as e:
95
+ logger.error(f"Failed to load model: {str(e)}")
96
+ raise
97
+
98
+ @app.get("/", response_model=HealthResponse)
99
+ async def root():
100
+ """Health check endpoint."""
101
+ return HealthResponse(
102
+ status="healthy" if model is not None else "loading",
103
+ model_loaded=model is not None,
104
+ device=device,
105
+ model_name="lingxusb/PlasmidGPT"
106
+ )
107
+
108
+ @app.get("/health", response_model=HealthResponse)
109
+ async def health():
110
+ """Health check endpoint."""
111
+ return HealthResponse(
112
+ status="healthy" if model is not None else "loading",
113
+ model_loaded=model is not None,
114
+ device=device,
115
+ model_name="lingxusb/PlasmidGPT"
116
+ )
117
+
118
+ @app.post("/generate", response_model=GenerationResponse)
119
+ async def generate_sequences(request: GenerationRequest):
120
+ """
121
+ Generate DNA sequences using PlasmidGPT.
122
+
123
+ Args:
124
+ request: Generation parameters
125
+
126
+ Returns:
127
+ Generated sequences with metadata
128
+ """
129
+ if model is None or tokenizer is None:
130
+ raise HTTPException(
131
+ status_code=503,
132
+ detail="Model is still loading. Please wait and try again."
133
+ )
134
+
135
+ try:
136
+ start_time = time.time()
137
+
138
+ # Tokenize input
139
+ inputs = tokenizer(request.prompt, return_tensors="pt").to(device)
140
+
141
+ # Generate sequences
142
+ with torch.no_grad():
143
+ outputs = model.generate(
144
+ inputs.input_ids,
145
+ max_length=request.max_length,
146
+ temperature=request.temperature,
147
+ num_return_sequences=request.num_return_sequences,
148
+ do_sample=request.do_sample,
149
+ repetition_penalty=request.repetition_penalty,
150
+ pad_token_id=tokenizer.pad_token_id or tokenizer.eos_token_id,
151
+ eos_token_id=tokenizer.eos_token_id
152
+ )
153
+
154
+ # Decode sequences
155
+ sequences = []
156
+ for output in outputs:
157
+ # Decode only the generated part (exclude prompt)
158
+ generated = output[inputs.input_ids.shape[1]:]
159
+ sequence = tokenizer.decode(generated, skip_special_tokens=True)
160
+ sequences.append(sequence)
161
+
162
+ generation_time = time.time() - start_time
163
+
164
+ return GenerationResponse(
165
+ sequences=sequences,
166
+ metadata={
167
+ "prompt": request.prompt,
168
+ "prompt_length": len(request.prompt),
169
+ "generated_lengths": [len(seq) for seq in sequences],
170
+ "device": device,
171
+ "model": "lingxusb/PlasmidGPT"
172
+ },
173
+ generation_time=generation_time
174
+ )
175
+
176
+ except Exception as e:
177
+ logger.error(f"Generation failed: {str(e)}")
178
+ raise HTTPException(
179
+ status_code=500,
180
+ detail=f"Generation failed: {str(e)}"
181
+ )
182
+
183
+ @app.post("/embed")
184
+ async def extract_embeddings(request: Dict[str, Any]):
185
+ """
186
+ Extract embeddings from sequences (placeholder - implement if needed).
187
+ """
188
+ raise HTTPException(
189
+ status_code=501,
190
+ detail="Embedding extraction not yet implemented in Space deployment"
191
+ )
192
+
193
+ if __name__ == "__main__":
194
+ import uvicorn
195
+ uvicorn.run(app, host="0.0.0.0", port=7860)
196
+
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ fastapi==0.104.1
2
+ uvicorn[standard]==0.24.0
3
+ torch>=2.0.0
4
+ transformers>=4.35.0
5
+ accelerate>=0.24.0
6
+ pydantic==2.5.0
7
+ python-multipart==0.0.6
8
+