setup_minio.sh 9.05 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
#!/bin/bash
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

# Script to setup MinIO and upload LoRA adapters from Hugging Face Hub

set -e

# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color

# Configuration
MINIO_DATA_DIR="${HOME}/dynamo_minio_data"
MINIO_ENDPOINT="http://localhost:9000"
MINIO_ACCESS_KEY="minioadmin"
MINIO_SECRET_KEY="minioadmin"
BUCKET_NAME="my-loras"

# Default LoRA to download (can be overridden)
HF_LORA_REPO="${HF_LORA_REPO:-Neural-Hacker/Qwen3-Math-Reasoning-LoRA}"
LORA_NAME="${LORA_NAME:-Neural-Hacker/Qwen3-Math-Reasoning-LoRA}"
# TEMP_DIR will be created using mktemp when needed
TEMP_DIR=""

# Parse command line arguments
MODE="full"
if [ "$1" = "--start" ]; then
    MODE="start"
elif [ "$1" = "--stop" ]; then
    MODE="stop"
elif [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
    MODE="help"
elif [ -n "$1" ]; then
    echo -e "${RED}Error: Unknown option '$1'${NC}"
    MODE="help"
fi

print_info() {
    echo -e "${YELLOW}$1${NC}"
}

print_success() {
    echo -e "${GREEN}$1${NC}"
}

print_error() {
    echo -e "${RED}$1${NC}"
}

# Show help message
show_help() {
    echo "Usage: $0 [OPTIONS]"
    echo ""
    echo "Setup MinIO and upload LoRA adapters from Hugging Face Hub"
    echo ""
    echo "Options:"
    echo "  (no options)  Run full setup: start MinIO, download and upload LoRA"
    echo "  --start       Only start MinIO container"
    echo "  --stop        Stop and remove MinIO container"
    echo "  --help, -h    Show this help message"
    echo ""
    echo "Environment Variables:"
    echo "  HF_LORA_REPO  Hugging Face repository (default: ${HF_LORA_REPO:-Neural-Hacker/Qwen3-Math-Reasoning-LoRA})"
    echo "  LORA_NAME     Local name for the LoRA (default: ${LORA_NAME:-Neural-Hacker/Qwen3-Math-Reasoning-LoRA})"
    echo ""
    echo "Examples:"
    echo "  $0                                    # Full setup"
    echo "  $0 --start                            # Start MinIO only"
    echo "  $0 --stop                             # Stop MinIO"
    echo "  HF_LORA_REPO=user/repo $0             # Use custom LoRA"
    echo ""
}

# Check if required tools are installed
check_dependencies() {
    print_info "Checking dependencies..."

    if ! command -v docker &> /dev/null; then
        echo "Error: docker is not installed"
        exit 1
    fi

    if ! command -v aws &> /dev/null; then
        echo "Error: aws-cli is not installed. Install with: pip install awscli"
        exit 1
    fi

    if ! command -v huggingface-cli &> /dev/null; then
        echo "Error: huggingface-cli is not installed. Install with: pip install huggingface-hub"
        exit 1
    fi

    print_success "All dependencies are installed"
}

# Start MinIO using Docker
start_minio() {
    print_info "Setting up MinIO..."

    # Create data directory
    mkdir -p "${MINIO_DATA_DIR}"

    # Stop and remove existing container if it exists
    docker stop dynamo-minio 2>/dev/null || true
    docker rm dynamo-minio 2>/dev/null || true

    # Start MinIO
    print_info "Starting MinIO container..."
    docker run -d \
        --name dynamo-minio \
        -p 9000:9000 \
        -p 9001:9001 \
        -v "${MINIO_DATA_DIR}:/data" \
        quay.io/minio/minio server /data \
        --console-address ":9001"

    # Wait for MinIO to be ready
    print_info "Waiting for MinIO to be ready..."
    for i in {1..30}; do
        if curl -s ${MINIO_ENDPOINT}/minio/health/live > /dev/null 2>&1; then
            print_success "MinIO is ready"
            break
        fi
        if [ $i -eq 30 ]; then
            echo "Error: MinIO did not start in time"
            exit 1
        fi
        sleep 1
    done

    print_success "MinIO started successfully"
    echo "  - MinIO API: ${MINIO_ENDPOINT}"
    echo "  - MinIO Console: http://localhost:9001"
    echo "  - Username: ${MINIO_ACCESS_KEY}"
    echo "  - Password: ${MINIO_SECRET_KEY}"
}

# Configure AWS CLI for MinIO
configure_aws_cli() {
    print_info "Configuring AWS CLI for MinIO..."

    export AWS_ACCESS_KEY_ID="${MINIO_ACCESS_KEY}"
    export AWS_SECRET_ACCESS_KEY="${MINIO_SECRET_KEY}"
    export AWS_ENDPOINT_URL="${MINIO_ENDPOINT}"

    # Create bucket if it doesn't exist
    if ! aws --endpoint-url=${MINIO_ENDPOINT} s3 ls s3://${BUCKET_NAME} 2>/dev/null; then
        print_info "Creating bucket: ${BUCKET_NAME}"
        aws --endpoint-url=${MINIO_ENDPOINT} s3 mb s3://${BUCKET_NAME}
        print_success "Bucket created"
    else
        print_success "Bucket already exists: ${BUCKET_NAME}"
    fi
}

# Download LoRA from Hugging Face Hub
download_lora_from_hf() {
    print_info "Downloading LoRA from Hugging Face Hub..."
    echo "  - Repository: ${HF_LORA_REPO}"
    echo "  - Local name: ${LORA_NAME}"

    # Create temporary directory using mktemp (global variable for cleanup)
    TEMP_DIR=$(mktemp -d -t lora_download_XXXXXX)

    # Download LoRA adapter files
    print_info "Downloading adapter files..."
    huggingface-cli download "${HF_LORA_REPO}" \
        --local-dir "${TEMP_DIR}" \
        --local-dir-use-symlinks False

    print_success "LoRA downloaded to ${TEMP_DIR}"

    # List downloaded files
    echo "Downloaded files:"
    ls -lh "${TEMP_DIR}"
}

# Upload LoRA to MinIO
upload_lora_to_minio() {
    print_info "Uploading LoRA to MinIO..."

    # Upload all files to S3
    aws --endpoint-url=${MINIO_ENDPOINT} s3 sync \
        "${TEMP_DIR}" \
        "s3://${BUCKET_NAME}/${LORA_NAME}" \
        --exclude "*.git*"

    print_success "LoRA uploaded to s3://${BUCKET_NAME}/${LORA_NAME}"

    # List uploaded files
    echo "Uploaded files:"
    aws --endpoint-url=${MINIO_ENDPOINT} s3 ls "s3://${BUCKET_NAME}/${LORA_NAME}/" --recursive
}

# Cleanup temp files
cleanup() {
    if [ -n "${TEMP_DIR}" ] && [ -d "${TEMP_DIR}" ]; then
        print_info "Cleaning up temporary files..."
        rm -rf "${TEMP_DIR}"
        print_success "Cleanup complete"
    fi
}

# Stop MinIO
stop_minio() {
    print_info "Stopping MinIO..."

    if docker ps | grep -q dynamo-minio; then
        docker stop dynamo-minio 2>/dev/null
        print_success "MinIO container stopped"
    else
        print_info "MinIO container is not running"
    fi

    if docker ps -a | grep -q dynamo-minio; then
        docker rm dynamo-minio 2>/dev/null
        print_success "MinIO container removed"
    fi

    echo ""
    echo "MinIO has been stopped."
    echo "Data is preserved in: ${MINIO_DATA_DIR}"
    echo ""
    echo "To start MinIO again:"
    echo "  $0 --start"
    echo ""
}

# Start MinIO only (without downloading/uploading LoRA)
start_only() {
    echo "========================================"
    echo "Starting MinIO"
    echo "========================================"
    echo ""

    start_minio
    echo ""

    echo "========================================"
    echo "MinIO Started!"
    echo "========================================"
    echo ""
    echo "MinIO is now running."
    echo ""
    echo "To upload a LoRA, run the full setup:"
    echo "  $0"
    echo ""
    echo "Or manually upload using AWS CLI:"
    echo "  export AWS_ACCESS_KEY_ID=${MINIO_ACCESS_KEY}"
    echo "  export AWS_SECRET_ACCESS_KEY=${MINIO_SECRET_KEY}"
    echo "  aws --endpoint-url=${MINIO_ENDPOINT} s3 cp your-lora/ s3://${BUCKET_NAME}/your-lora/ --recursive"
    echo ""
    echo "To stop MinIO:"
    echo "  $0 --stop"
    echo ""
}

# Full setup (start MinIO + download/upload LoRA)
full_setup() {
    echo "========================================"
    echo "MinIO Setup & LoRA Upload Script"
    echo "========================================"
    echo ""

    check_dependencies
    echo ""

    start_minio
    echo ""

    configure_aws_cli
    echo ""

    download_lora_from_hf
    echo ""

    upload_lora_to_minio
    echo ""

    cleanup
    echo ""

    echo "========================================"
    echo "Setup Complete!"
    echo "========================================"
    echo ""
    echo "MinIO is running and LoRA has been uploaded."
    echo ""
    echo "Next steps:"
    echo "  1. Run the Dynamo service with LoRA support:"
    echo "     ./agg_lora_s3.sh"
    echo ""
    echo "  2. Load the LoRA adapter:"
    echo "     curl -X POST http://localhost:8081/v1/loras \\"
    echo "       -H \"Content-Type: application/json\" \\"
    echo "       -d '{\"lora_name\": \"${LORA_NAME}\", \"source\": {\"uri\": \"s3://${BUCKET_NAME}/${LORA_NAME}\"}}'"
    echo ""
    echo "  3. Run inference with the LoRA:"
    echo "     curl -X POST http://localhost:8000/v1/chat/completions \\"
    echo "       -H \"Content-Type: application/json\" \\"
    echo "       -d '{\"model\": \"${LORA_NAME}\", \"messages\": [{\"role\": \"user\", \"content\": \"your prompt here\"}]}'"
    echo ""
    echo "To stop MinIO:"
    echo "  $0 --stop"
    echo ""
}

# Main execution
case "$MODE" in
    start)
        start_only
        ;;
    stop)
        stop_minio
        ;;
    help)
        show_help
        exit 0
        ;;
    full)
        full_setup
        ;;
    *)
        echo "Error: Unknown mode '$MODE'"
        show_help
        exit 1
        ;;
esac