Spaces:
Sleeping
Sleeping
Add Vertex AI / Gemini Flash setup and diagnostic scripts
Browse filesCo-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GEMINI_3_FLASH_SETUP.md +764 -0
- check_available_models.py +95 -0
- check_vertex_ai_access.py +217 -0
- fix_vertex_ai_config.py +287 -0
- vertex_ai_fixed_config.py +68 -0
GEMINI_3_FLASH_SETUP.md
ADDED
|
@@ -0,0 +1,764 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Налаштування Gemini 3 Flash Preview з GCP Service Account
|
| 2 |
+
|
| 3 |
+
## Вступ
|
| 4 |
+
|
| 5 |
+
Цей документ описує детальну інструкцію з налаштування та використання моделей Gemini з доступом через `GCP_SERVICE_ACCOUNT_B64`.
|
| 6 |
+
|
| 7 |
+
### ⚠️ ВАЖЛИВО: Статус доступності
|
| 8 |
+
|
| 9 |
+
**Результат перевірки (2026-02-02):**
|
| 10 |
+
- ✗ `gemini-3-flash-preview` - **НЕ ДОСТУПНА** у вашому проекті
|
| 11 |
+
- ✓ `gemini-2.0-flash` - **ДОСТУПНА** ✅
|
| 12 |
+
|
| 13 |
+
**Рекомендація:** Використовуйте `gemini-2.0-flash` замість `gemini-3-flash-preview` до отримання доступу до нової моделі.
|
| 14 |
+
|
| 15 |
+
---
|
| 16 |
+
|
| 17 |
+
## Результати Перевірки Доступності
|
| 18 |
+
|
| 19 |
+
### Перевірка від 2026-02-02
|
| 20 |
+
|
| 21 |
+
```
|
| 22 |
+
✓ GCP_SERVICE_ACCOUNT_B64 знайдено
|
| 23 |
+
✓ Base64 успішно декодовано
|
| 24 |
+
✓ Project ID: gen-lang-client-0514505508
|
| 25 |
+
✓ Client Email: llmphaseone@gen-lang-client-0514505508.iam.gserviceaccount.com
|
| 26 |
+
✓ Credentials успішно створено
|
| 27 |
+
✓ Vertex AI ініціалізовано
|
| 28 |
+
✓ Модель завантажена
|
| 29 |
+
|
| 30 |
+
✗ gemini-3-flash-preview - НЕ ДОСТУПНА (404 Not Found)
|
| 31 |
+
✓ gemini-2.0-flash - ДОСТУПНА ✅
|
| 32 |
+
```
|
| 33 |
+
|
| 34 |
+
### Доступні Моделі у Вашому Проекті
|
| 35 |
+
|
| 36 |
+
| Модель | Статус | Рекомендація |
|
| 37 |
+
|--------|--------|--------------|
|
| 38 |
+
| gemini-3-flash-preview | ✗ Недоступна | Очікування доступу |
|
| 39 |
+
| gemini-2.0-flash | ✓ Доступна | **Використовуйте цю** |
|
| 40 |
+
| gemini-1.5-pro | ✗ Недоступна | - |
|
| 41 |
+
| gemini-1.5-flash | ✗ Недоступна | - |
|
| 42 |
+
|
| 43 |
+
---
|
| 44 |
+
|
| 45 |
+
## 1. Підготовка GCP Service Account
|
| 46 |
+
|
| 47 |
+
### 1.1 Декодування Base64 Service Account
|
| 48 |
+
|
| 49 |
+
Ваш `GCP_SERVICE_ACCOUNT_B64` вже закодований в Base64. Ось як його декодувати та використовувати:
|
| 50 |
+
|
| 51 |
+
```python
|
| 52 |
+
import base64
|
| 53 |
+
import json
|
| 54 |
+
import os
|
| 55 |
+
from google.auth import default
|
| 56 |
+
from google.oauth2 import service_account
|
| 57 |
+
import google.generativeai as genai
|
| 58 |
+
|
| 59 |
+
def setup_gcp_auth():
|
| 60 |
+
"""
|
| 61 |
+
Налаштування автентифікації GCP з Base64 encoded service account
|
| 62 |
+
|
| 63 |
+
Returns:
|
| 64 |
+
tuple: (credentials, service_account_dict)
|
| 65 |
+
"""
|
| 66 |
+
|
| 67 |
+
# Отримати Base64 encoded service account з .env
|
| 68 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 69 |
+
|
| 70 |
+
if not service_account_b64:
|
| 71 |
+
raise ValueError("GCP_SERVICE_ACCOUNT_B64 не знайдено в .env")
|
| 72 |
+
|
| 73 |
+
# Декодувати Base64
|
| 74 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 75 |
+
service_account_dict = json.loads(service_account_json)
|
| 76 |
+
|
| 77 |
+
# Створити credentials
|
| 78 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 79 |
+
service_account_dict,
|
| 80 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 81 |
+
)
|
| 82 |
+
|
| 83 |
+
return credentials, service_account_dict
|
| 84 |
+
```
|
| 85 |
+
|
| 86 |
+
### 1.2 Ініціалізація Vertex AI
|
| 87 |
+
|
| 88 |
+
```python
|
| 89 |
+
def initialize_vertex_ai():
|
| 90 |
+
"""
|
| 91 |
+
Ініціалізація Vertex AI з GCP credentials
|
| 92 |
+
|
| 93 |
+
Returns:
|
| 94 |
+
str: Project ID з service account
|
| 95 |
+
"""
|
| 96 |
+
|
| 97 |
+
import vertexai
|
| 98 |
+
|
| 99 |
+
credentials, service_account_dict = setup_gcp_auth()
|
| 100 |
+
project_id = service_account_dict.get('project_id')
|
| 101 |
+
|
| 102 |
+
# Ініціалізація Vertex AI
|
| 103 |
+
vertexai.init(project=project_id, credentials=credentials)
|
| 104 |
+
|
| 105 |
+
return project_id
|
| 106 |
+
```
|
| 107 |
+
|
| 108 |
+
---
|
| 109 |
+
|
| 110 |
+
## 2. Основний Клієнт Gemini
|
| 111 |
+
|
| 112 |
+
### 2.1 Клас GeminiClient
|
| 113 |
+
|
| 114 |
+
```python
|
| 115 |
+
from vertexai.generative_models import GenerativeModel
|
| 116 |
+
from typing import Optional, Generator
|
| 117 |
+
|
| 118 |
+
class GeminiClient:
|
| 119 |
+
"""
|
| 120 |
+
Клієнт для роботи з Gemini моделями через Vertex AI
|
| 121 |
+
|
| 122 |
+
Attributes:
|
| 123 |
+
model_name (str): Назва моделі (за замовчуванням: gemini-2.0-flash)
|
| 124 |
+
project_id (str): ID проекту GCP
|
| 125 |
+
"""
|
| 126 |
+
|
| 127 |
+
def __init__(self, model_name: str = "gemini-2.0-flash"):
|
| 128 |
+
"""
|
| 129 |
+
Ініціалізація клієнта
|
| 130 |
+
|
| 131 |
+
Args:
|
| 132 |
+
model_name (str): Назва моделі для використання
|
| 133 |
+
За замовчуванням: gemini-2.0-flash (доступна)
|
| 134 |
+
Альтернатива: gemini-3-flash-preview (якщо отримаєте доступ)
|
| 135 |
+
"""
|
| 136 |
+
self.model_name = model_name
|
| 137 |
+
self.project_id = initialize_vertex_ai()
|
| 138 |
+
|
| 139 |
+
def generate_text(
|
| 140 |
+
self,
|
| 141 |
+
prompt: str,
|
| 142 |
+
temperature: float = 0.7,
|
| 143 |
+
max_tokens: int = 2048,
|
| 144 |
+
top_p: float = 0.95,
|
| 145 |
+
top_k: int = 40
|
| 146 |
+
) -> str:
|
| 147 |
+
"""
|
| 148 |
+
Генерація тексту з Gemini
|
| 149 |
+
|
| 150 |
+
Args:
|
| 151 |
+
prompt (str): Вхідний промпт
|
| 152 |
+
temperature (float): Температура генерації (0.0-1.0)
|
| 153 |
+
max_tokens (int): Максимальна кількість токенів
|
| 154 |
+
top_p (float): Nucleus sampling параметр
|
| 155 |
+
top_k (int): Top-K sampling параметр
|
| 156 |
+
|
| 157 |
+
Returns:
|
| 158 |
+
str: Згенерований текст
|
| 159 |
+
|
| 160 |
+
Raises:
|
| 161 |
+
Exception: Якщо сталася помилка при генерації
|
| 162 |
+
"""
|
| 163 |
+
|
| 164 |
+
try:
|
| 165 |
+
model = GenerativeModel(self.model_name)
|
| 166 |
+
|
| 167 |
+
response = model.generate_content(
|
| 168 |
+
prompt,
|
| 169 |
+
generation_config={
|
| 170 |
+
"temperature": temperature,
|
| 171 |
+
"max_output_tokens": max_tokens,
|
| 172 |
+
"top_p": top_p,
|
| 173 |
+
"top_k": top_k,
|
| 174 |
+
}
|
| 175 |
+
)
|
| 176 |
+
|
| 177 |
+
return response.text
|
| 178 |
+
|
| 179 |
+
except Exception as e:
|
| 180 |
+
print(f"Помилка при генерації тексту: {e}")
|
| 181 |
+
raise
|
| 182 |
+
|
| 183 |
+
def stream_text(
|
| 184 |
+
self,
|
| 185 |
+
prompt: str,
|
| 186 |
+
temperature: float = 0.7,
|
| 187 |
+
max_tokens: int = 2048
|
| 188 |
+
) -> Generator[str, None, None]:
|
| 189 |
+
"""
|
| 190 |
+
Потокова генерація тексту
|
| 191 |
+
|
| 192 |
+
Args:
|
| 193 |
+
prompt (str): Вхідний промпт
|
| 194 |
+
temperature (float): Температура генерації
|
| 195 |
+
max_tokens (int): Максимальна кількість токенів
|
| 196 |
+
|
| 197 |
+
Yields:
|
| 198 |
+
str: Частини згенерованого тексту
|
| 199 |
+
"""
|
| 200 |
+
|
| 201 |
+
model = GenerativeModel(self.model_name)
|
| 202 |
+
|
| 203 |
+
response = model.generate_content(
|
| 204 |
+
prompt,
|
| 205 |
+
generation_config={
|
| 206 |
+
"temperature": temperature,
|
| 207 |
+
"max_output_tokens": max_tokens,
|
| 208 |
+
},
|
| 209 |
+
stream=True
|
| 210 |
+
)
|
| 211 |
+
|
| 212 |
+
for chunk in response:
|
| 213 |
+
if chunk.text:
|
| 214 |
+
yield chunk.text
|
| 215 |
+
|
| 216 |
+
def chat_conversation(self, messages: list) -> str:
|
| 217 |
+
"""
|
| 218 |
+
Чат-конверсація з Gemini
|
| 219 |
+
|
| 220 |
+
Args:
|
| 221 |
+
messages (list): Список повідомлень для чату
|
| 222 |
+
|
| 223 |
+
Returns:
|
| 224 |
+
str: Відповідь моделі
|
| 225 |
+
"""
|
| 226 |
+
|
| 227 |
+
model = GenerativeModel(self.model_name)
|
| 228 |
+
chat = model.start_chat()
|
| 229 |
+
|
| 230 |
+
for message in messages:
|
| 231 |
+
response = chat.send_message(message)
|
| 232 |
+
|
| 233 |
+
return response.text
|
| 234 |
+
|
| 235 |
+
def count_tokens(self, text: str) -> int:
|
| 236 |
+
"""
|
| 237 |
+
Підрахунок кількості токенів
|
| 238 |
+
|
| 239 |
+
Args:
|
| 240 |
+
text (str): Текст для підрахунку
|
| 241 |
+
|
| 242 |
+
Returns:
|
| 243 |
+
int: Кількість токенів
|
| 244 |
+
"""
|
| 245 |
+
|
| 246 |
+
model = GenerativeModel(self.model_name)
|
| 247 |
+
response = model.count_tokens(text)
|
| 248 |
+
return response.total_tokens
|
| 249 |
+
```
|
| 250 |
+
|
| 251 |
+
---
|
| 252 |
+
|
| 253 |
+
## 3. Приклади Використання
|
| 254 |
+
|
| 255 |
+
### 3.1 Простий Запит
|
| 256 |
+
|
| 257 |
+
```python
|
| 258 |
+
# Ініціалізація з доступною моделлю
|
| 259 |
+
client = GeminiClient() # Використовує gemini-2.0-flash за замовчуванням
|
| 260 |
+
|
| 261 |
+
# АБО явно вказати модель
|
| 262 |
+
client = GeminiClient(model_name="gemini-2.0-flash")
|
| 263 |
+
|
| 264 |
+
# Простий запит
|
| 265 |
+
response = client.generate_text(
|
| 266 |
+
prompt="Поясни, що таке машинне навчання простою мовою",
|
| 267 |
+
temperature=0.7,
|
| 268 |
+
max_tokens=1024
|
| 269 |
+
)
|
| 270 |
+
print(response)
|
| 271 |
+
```
|
| 272 |
+
|
| 273 |
+
**Очікуваний результат:**
|
| 274 |
+
```
|
| 275 |
+
Машинне навчання - це область штучного інтелекту, яка дозволяє комп'ютерам
|
| 276 |
+
навчатися на основі даних без явного програмування...
|
| 277 |
+
```
|
| 278 |
+
|
| 279 |
+
### 3.2 Потокова Генерація
|
| 280 |
+
|
| 281 |
+
```python
|
| 282 |
+
# Потокова генерація з реальним часом
|
| 283 |
+
print("Потокова генерація:")
|
| 284 |
+
for chunk in client.stream_text(
|
| 285 |
+
prompt="Напиши вірш про весну",
|
| 286 |
+
max_tokens=500
|
| 287 |
+
):
|
| 288 |
+
print(chunk, end="", flush=True)
|
| 289 |
+
print() # Новий рядок в кінці
|
| 290 |
+
```
|
| 291 |
+
|
| 292 |
+
### 3.3 Чат-Конверсація
|
| 293 |
+
|
| 294 |
+
```python
|
| 295 |
+
# Чат-конверсація з кількома повідомленнями
|
| 296 |
+
messages = [
|
| 297 |
+
"Привіт! Як дела?",
|
| 298 |
+
"Розкажи мені про штучний інтелект",
|
| 299 |
+
"Які його основні застосування?"
|
| 300 |
+
]
|
| 301 |
+
|
| 302 |
+
chat_response = client.chat_conversation(messages)
|
| 303 |
+
print(chat_response)
|
| 304 |
+
```
|
| 305 |
+
|
| 306 |
+
### 3.4 Підрахунок Токенів
|
| 307 |
+
|
| 308 |
+
```python
|
| 309 |
+
# Перевірка кількості токенів перед запитом
|
| 310 |
+
text = "Це довгий текст, який я хочу обробити..."
|
| 311 |
+
token_count = client.count_tokens(text)
|
| 312 |
+
print(f"Кількість токенів: {token_count}")
|
| 313 |
+
```
|
| 314 |
+
|
| 315 |
+
---
|
| 316 |
+
|
| 317 |
+
## 4. Встановлення Залежностей
|
| 318 |
+
|
| 319 |
+
### 4.1 Оновлення requirements.txt
|
| 320 |
+
|
| 321 |
+
Додайте наступні залежності до `requirements.txt`:
|
| 322 |
+
|
| 323 |
+
```
|
| 324 |
+
google-generativeai>=0.3.0
|
| 325 |
+
google-auth>=2.25.0
|
| 326 |
+
google-auth-oauthlib>=1.1.0
|
| 327 |
+
google-auth-httplib2>=0.2.0
|
| 328 |
+
google-cloud-aiplatform>=1.50.0
|
| 329 |
+
vertexai>=1.0.0
|
| 330 |
+
python-dotenv>=1.0.0
|
| 331 |
+
```
|
| 332 |
+
|
| 333 |
+
### 4.2 Встановлення Пакетів
|
| 334 |
+
|
| 335 |
+
```bash
|
| 336 |
+
pip install -r requirements.txt
|
| 337 |
+
```
|
| 338 |
+
|
| 339 |
+
---
|
| 340 |
+
|
| 341 |
+
## 5. Налаштування Змінних Середовища
|
| 342 |
+
|
| 343 |
+
### 5.1 Структура .env
|
| 344 |
+
|
| 345 |
+
Ваш `.env` файл повинен містити:
|
| 346 |
+
|
| 347 |
+
```env
|
| 348 |
+
# Gemini API Key
|
| 349 |
+
GEMINI_API_KEY=
|
| 350 |
+
|
| 351 |
+
# GCP Service Account (Base64 encoded)
|
| 352 |
+
GCP_SERVICE_ACCOUNT_B64=ewoidHlwZSI6ICJzX2FjY291bnQiLC...
|
| 353 |
+
|
| 354 |
+
# Додаткові налаштування
|
| 355 |
+
DEBUG=true
|
| 356 |
+
LOG_LEVEL=DEBUG
|
| 357 |
+
```
|
| 358 |
+
|
| 359 |
+
### 5.2 Завантаження Змінних
|
| 360 |
+
|
| 361 |
+
```python
|
| 362 |
+
from dotenv import load_dotenv
|
| 363 |
+
import os
|
| 364 |
+
|
| 365 |
+
# Завантажити змінні з .env
|
| 366 |
+
load_dotenv()
|
| 367 |
+
|
| 368 |
+
# Перевірити наявність ключів
|
| 369 |
+
required_vars = ['GEMINI_API_KEY', 'GCP_SERVICE_ACCOUNT_B64']
|
| 370 |
+
for var in required_vars:
|
| 371 |
+
if not os.getenv(var):
|
| 372 |
+
raise ValueError(f"Змінна {var} не знайдена в .env")
|
| 373 |
+
```
|
| 374 |
+
|
| 375 |
+
---
|
| 376 |
+
|
| 377 |
+
## 6. Обробка Помилок та Логування
|
| 378 |
+
|
| 379 |
+
### 6.1 Розширена Версія з Логуванням
|
| 380 |
+
|
| 381 |
+
```python
|
| 382 |
+
import logging
|
| 383 |
+
from typing import Optional
|
| 384 |
+
|
| 385 |
+
# Налаштування логування
|
| 386 |
+
logging.basicConfig(
|
| 387 |
+
level=logging.INFO,
|
| 388 |
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
| 389 |
+
)
|
| 390 |
+
logger = logging.getLogger(__name__)
|
| 391 |
+
|
| 392 |
+
class GeminiClientWithLogging(GeminiClient):
|
| 393 |
+
"""
|
| 394 |
+
Розширена версія GeminiClient з логуванням
|
| 395 |
+
"""
|
| 396 |
+
|
| 397 |
+
def generate_text(self, prompt: str, **kwargs) -> str:
|
| 398 |
+
"""Генерація тексту з логуванням"""
|
| 399 |
+
|
| 400 |
+
logger.info(f"Запит до Gemini: {prompt[:100]}...")
|
| 401 |
+
|
| 402 |
+
try:
|
| 403 |
+
response = super().generate_text(prompt, **kwargs)
|
| 404 |
+
logger.info(f"Успішна відповідь: {len(response)} символів")
|
| 405 |
+
return response
|
| 406 |
+
|
| 407 |
+
except Exception as e:
|
| 408 |
+
logger.error(f"Помилка Gemini: {str(e)}", exc_info=True)
|
| 409 |
+
raise
|
| 410 |
+
|
| 411 |
+
def stream_text(self, prompt: str, **kwargs):
|
| 412 |
+
"""Потокова генерація з логуванням"""
|
| 413 |
+
|
| 414 |
+
logger.info(f"Потокова генерація: {prompt[:100]}...")
|
| 415 |
+
|
| 416 |
+
try:
|
| 417 |
+
for chunk in super().stream_text(prompt, **kwargs):
|
| 418 |
+
yield chunk
|
| 419 |
+
logger.info("Потокова генерація завершена")
|
| 420 |
+
|
| 421 |
+
except Exception as e:
|
| 422 |
+
logger.error(f"Помилка потокової генерації: {str(e)}", exc_info=True)
|
| 423 |
+
raise
|
| 424 |
+
```
|
| 425 |
+
|
| 426 |
+
### 6.2 Обробка Специфічних Помилок
|
| 427 |
+
|
| 428 |
+
```python
|
| 429 |
+
class GeminiClientWithErrorHandling(GeminiClient):
|
| 430 |
+
"""Клієнт з детальною обробкою помилок"""
|
| 431 |
+
|
| 432 |
+
def generate_text(self, prompt: str, **kwargs) -> Optional[str]:
|
| 433 |
+
"""Генерація з обробкою помилок"""
|
| 434 |
+
|
| 435 |
+
try:
|
| 436 |
+
return super().generate_text(prompt, **kwargs)
|
| 437 |
+
|
| 438 |
+
except ValueError as e:
|
| 439 |
+
logger.error(f"Помилка значення: {e}")
|
| 440 |
+
return None
|
| 441 |
+
|
| 442 |
+
except ConnectionError as e:
|
| 443 |
+
logger.error(f"Помилка з'єднання: {e}")
|
| 444 |
+
return None
|
| 445 |
+
|
| 446 |
+
except Exception as e:
|
| 447 |
+
logger.error(f"Невідома помилка: {e}")
|
| 448 |
+
return None
|
| 449 |
+
```
|
| 450 |
+
|
| 451 |
+
---
|
| 452 |
+
|
| 453 |
+
## 7. Перевірка Налаштування
|
| 454 |
+
|
| 455 |
+
### 7.1 Функція Верифікації
|
| 456 |
+
|
| 457 |
+
```python
|
| 458 |
+
def verify_setup() -> bool:
|
| 459 |
+
"""
|
| 460 |
+
Перевірка правильності налаштування
|
| 461 |
+
|
| 462 |
+
Returns:
|
| 463 |
+
bool: True якщо все налаштовано правильно
|
| 464 |
+
"""
|
| 465 |
+
|
| 466 |
+
try:
|
| 467 |
+
# Перевірка GCP Service Account
|
| 468 |
+
credentials, service_account_dict = setup_gcp_auth()
|
| 469 |
+
print(f"✓ GCP Service Account: {service_account_dict.get('client_email')}")
|
| 470 |
+
print(f"✓ Project ID: {service_account_dict.get('project_id')}")
|
| 471 |
+
|
| 472 |
+
# Перевірка Gemini API
|
| 473 |
+
client = GeminiClient()
|
| 474 |
+
print(f"✓ Модель: {client.model_name}")
|
| 475 |
+
|
| 476 |
+
# Тестовий запит
|
| 477 |
+
test_response = client.generate_text(
|
| 478 |
+
"Привіт! Скажи мені одне слово.",
|
| 479 |
+
max_tokens=10
|
| 480 |
+
)
|
| 481 |
+
print(f"✓ Gemini працює: {test_response[:50]}...")
|
| 482 |
+
|
| 483 |
+
return True
|
| 484 |
+
|
| 485 |
+
except Exception as e:
|
| 486 |
+
print(f"✗ Помилка налаштування: {e}")
|
| 487 |
+
logger.error(f"Помилка верифікації: {e}", exc_info=True)
|
| 488 |
+
return False
|
| 489 |
+
```
|
| 490 |
+
|
| 491 |
+
### 7.2 Запуск Верифікації
|
| 492 |
+
|
| 493 |
+
```python
|
| 494 |
+
if __name__ == "__main__":
|
| 495 |
+
from dotenv import load_dotenv
|
| 496 |
+
|
| 497 |
+
# Завантажити змінні середовища
|
| 498 |
+
load_dotenv()
|
| 499 |
+
|
| 500 |
+
# Запустити перевірку
|
| 501 |
+
if verify_setup():
|
| 502 |
+
print("\n✓ Система готова до роботи!")
|
| 503 |
+
else:
|
| 504 |
+
print("\n✗ Помилка налаштування системи")
|
| 505 |
+
exit(1)
|
| 506 |
+
```
|
| 507 |
+
|
| 508 |
+
---
|
| 509 |
+
|
| 510 |
+
## 8. Повний Приклад Застосування
|
| 511 |
+
|
| 512 |
+
### 8.1 main.py
|
| 513 |
+
|
| 514 |
+
```python
|
| 515 |
+
#!/usr/bin/env python3
|
| 516 |
+
"""
|
| 517 |
+
Основний модуль для роботи з Gemini моделями через Vertex AI
|
| 518 |
+
"""
|
| 519 |
+
|
| 520 |
+
import os
|
| 521 |
+
import sys
|
| 522 |
+
from dotenv import load_dotenv
|
| 523 |
+
import logging
|
| 524 |
+
|
| 525 |
+
# Налаштування логування
|
| 526 |
+
logging.basicConfig(
|
| 527 |
+
level=logging.INFO,
|
| 528 |
+
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
| 529 |
+
)
|
| 530 |
+
logger = logging.getLogger(__name__)
|
| 531 |
+
|
| 532 |
+
# Завантажити змінні середовища
|
| 533 |
+
load_dotenv()
|
| 534 |
+
|
| 535 |
+
# Імпорт класів
|
| 536 |
+
from gemini_client import GeminiClientWithLogging, verify_setup
|
| 537 |
+
|
| 538 |
+
def main():
|
| 539 |
+
"""Основна функція"""
|
| 540 |
+
|
| 541 |
+
# Перевірка налаштування
|
| 542 |
+
if not verify_setup():
|
| 543 |
+
logger.error("Помилка налаштування")
|
| 544 |
+
sys.exit(1)
|
| 545 |
+
|
| 546 |
+
# Ініціалізація клієнта з доступною моделлю
|
| 547 |
+
client = GeminiClientWithLogging(model_name="gemini-2.0-flash")
|
| 548 |
+
|
| 549 |
+
# Приклад 1: Простий запит
|
| 550 |
+
print("\n=== Приклад 1: Простий запит ===")
|
| 551 |
+
response = client.generate_text(
|
| 552 |
+
"Що таке Python?",
|
| 553 |
+
max_tokens=200
|
| 554 |
+
)
|
| 555 |
+
print(response)
|
| 556 |
+
|
| 557 |
+
# Приклад 2: Потокова генерація
|
| 558 |
+
print("\n=== Приклад 2: Потокова генерація ===")
|
| 559 |
+
for chunk in client.stream_text(
|
| 560 |
+
"Напиши короткий вірш про програмування",
|
| 561 |
+
max_tokens=300
|
| 562 |
+
):
|
| 563 |
+
print(chunk, end="", flush=True)
|
| 564 |
+
print()
|
| 565 |
+
|
| 566 |
+
# Приклад 3: Чат
|
| 567 |
+
print("\n=== Приклад 3: Чат-конверсація ===")
|
| 568 |
+
messages = [
|
| 569 |
+
"Привіт!",
|
| 570 |
+
"Розкажи мені про машинне навчання",
|
| 571 |
+
]
|
| 572 |
+
response = client.chat_conversation(messages)
|
| 573 |
+
print(response)
|
| 574 |
+
|
| 575 |
+
if __name__ == "__main__":
|
| 576 |
+
main()
|
| 577 |
+
```
|
| 578 |
+
|
| 579 |
+
---
|
| 580 |
+
|
| 581 |
+
## 9. Параметри Генерації
|
| 582 |
+
|
| 583 |
+
### 9.1 Опис Параметрів
|
| 584 |
+
|
| 585 |
+
| Параметр | Діапазон | Опис |
|
| 586 |
+
|----------|----------|------|
|
| 587 |
+
| `temperature` | 0.0 - 1.0 | Контролює випадковість. 0 = детерміністично, 1 = максимально випадково |
|
| 588 |
+
| `max_tokens` | 1 - 32000 | Максимальна довжина відповіді |
|
| 589 |
+
| `top_p` | 0.0 - 1.0 | Nucleus sampling. Вибирає з найймовірніших токенів |
|
| 590 |
+
| `top_k` | 1 - 40 | Вибирає з K найймовірніших токенів |
|
| 591 |
+
|
| 592 |
+
### 9.2 Рекомендовані Налаштування
|
| 593 |
+
|
| 594 |
+
**Для творчих завдань:**
|
| 595 |
+
```python
|
| 596 |
+
client.generate_text(
|
| 597 |
+
prompt="Напиши історію...",
|
| 598 |
+
temperature=0.9,
|
| 599 |
+
top_p=0.95,
|
| 600 |
+
max_tokens=2048
|
| 601 |
+
)
|
| 602 |
+
```
|
| 603 |
+
|
| 604 |
+
**Для фактичних запитів:**
|
| 605 |
+
```python
|
| 606 |
+
client.generate_text(
|
| 607 |
+
prompt="Яка столиця України?",
|
| 608 |
+
temperature=0.2,
|
| 609 |
+
top_p=0.5,
|
| 610 |
+
max_tokens=512
|
| 611 |
+
)
|
| 612 |
+
```
|
| 613 |
+
|
| 614 |
+
**Для кодування:**
|
| 615 |
+
```python
|
| 616 |
+
client.generate_text(
|
| 617 |
+
prompt="Напиши функцію на Python...",
|
| 618 |
+
temperature=0.5,
|
| 619 |
+
top_p=0.8,
|
| 620 |
+
max_tokens=1024
|
| 621 |
+
)
|
| 622 |
+
```
|
| 623 |
+
|
| 624 |
+
---
|
| 625 |
+
|
| 626 |
+
## 10. Рекомендації та Best Practices
|
| 627 |
+
|
| 628 |
+
### 10.1 Безпека
|
| 629 |
+
|
| 630 |
+
- ✓ Ніколи не комітьте `.env` файл в Git
|
| 631 |
+
- ✓ Використовуйте `.gitignore` для захисту чутливих даних
|
| 632 |
+
- ✓ Регулярно ротуйте API ключі
|
| 633 |
+
- ✓ Обмежуйте доступ до GCP Service Account
|
| 634 |
+
|
| 635 |
+
### 10.2 Оптимізація
|
| 636 |
+
|
| 637 |
+
- ✓ Кешуйте результати для повторюваних запитів
|
| 638 |
+
- ✓ Використовуйте потокову генерацію для довгих текстів
|
| 639 |
+
- ✓ Підраховуйте токени перед запитом
|
| 640 |
+
- ✓ Встановлюйте розумні ліміти на `max_tokens`
|
| 641 |
+
|
| 642 |
+
### 10.3 Обробка Помилок
|
| 643 |
+
|
| 644 |
+
- ✓ Завжди обробляйте винятки
|
| 645 |
+
- ✓ Логуйте помилки для налагодження
|
| 646 |
+
- ✓ Реалізуйте retry логіку для тимчасових помилок
|
| 647 |
+
- ✓ Встановлюйте timeout для запитів
|
| 648 |
+
|
| 649 |
+
---
|
| 650 |
+
|
| 651 |
+
## 11. Отримання Доступу до gemini-3-flash-preview
|
| 652 |
+
|
| 653 |
+
### 11.1 Як Отримат�� Доступ
|
| 654 |
+
|
| 655 |
+
Якщо вам потрібна модель `gemini-3-flash-preview`, виконайте наступні кроки:
|
| 656 |
+
|
| 657 |
+
1. **Перейдіть до GCP Console:**
|
| 658 |
+
- Відкрийте [Google Cloud Console](https://console.cloud.google.com/)
|
| 659 |
+
- Виберіть ваш проект: `gen-lang-client-0514505508`
|
| 660 |
+
|
| 661 |
+
2. **Перейдіть до Vertex AI:**
|
| 662 |
+
- Меню → Vertex AI → Model Garden
|
| 663 |
+
- Пошук: "gemini-3-flash-preview"
|
| 664 |
+
|
| 665 |
+
3. **Запросіть Доступ:**
|
| 666 |
+
- Натисніть на модель
|
| 667 |
+
- Натисніть "Request Access" або "Enable"
|
| 668 |
+
- Дочекайтеся схвалення (зазвичай миттєво)
|
| 669 |
+
|
| 670 |
+
4. **Перевірте Доступ:**
|
| 671 |
+
```bash
|
| 672 |
+
python check_available_models.py
|
| 673 |
+
```
|
| 674 |
+
|
| 675 |
+
### 11.2 Альтернативні Способи
|
| 676 |
+
|
| 677 |
+
**Через gcloud CLI:**
|
| 678 |
+
```bash
|
| 679 |
+
gcloud ai models list --project=gen-lang-client-0514505508
|
| 680 |
+
```
|
| 681 |
+
|
| 682 |
+
**Через Python:**
|
| 683 |
+
```python
|
| 684 |
+
from google.cloud import aiplatform
|
| 685 |
+
|
| 686 |
+
aiplatform.init(project='gen-lang-client-0514505508')
|
| 687 |
+
models = aiplatform.Model.list()
|
| 688 |
+
for model in models:
|
| 689 |
+
print(model.display_name)
|
| 690 |
+
```
|
| 691 |
+
|
| 692 |
+
---
|
| 693 |
+
|
| 694 |
+
## 12. Розв'язання Проблем
|
| 695 |
+
|
| 696 |
+
### 12.1 Помилка: "GCP_SERVICE_ACCOUNT_B64 не знайдено"
|
| 697 |
+
|
| 698 |
+
**Рішення:**
|
| 699 |
+
```bash
|
| 700 |
+
# Перевірити наявність .env файлу
|
| 701 |
+
ls -la .env
|
| 702 |
+
|
| 703 |
+
# Перевірити вміст
|
| 704 |
+
cat .env | grep GCP_SERVICE_ACCOUNT_B64
|
| 705 |
+
```
|
| 706 |
+
|
| 707 |
+
### 12.2 Помилка: "Invalid API Key"
|
| 708 |
+
|
| 709 |
+
**Рішення:**
|
| 710 |
+
```python
|
| 711 |
+
# Перевірити API ключ
|
| 712 |
+
import os
|
| 713 |
+
print(os.getenv('GEMINI_API_KEY'))
|
| 714 |
+
|
| 715 |
+
# Переконатися, що ключ активний в GCP Console
|
| 716 |
+
```
|
| 717 |
+
|
| 718 |
+
### 12.3 Помилка: "Model not found"
|
| 719 |
+
|
| 720 |
+
**Рішення:**
|
| 721 |
+
```python
|
| 722 |
+
# Перевірити доступні моделі
|
| 723 |
+
python check_available_models.py
|
| 724 |
+
|
| 725 |
+
# Використовувати доступну модель
|
| 726 |
+
client = GeminiClient(model_name="gemini-2.0-flash")
|
| 727 |
+
```
|
| 728 |
+
|
| 729 |
+
### 12.4 Помилка: "404 Publisher Model not found"
|
| 730 |
+
|
| 731 |
+
**Причина:** Модель недоступна у вашому проекті
|
| 732 |
+
|
| 733 |
+
**Рішення:**
|
| 734 |
+
1. Запросіть доступ через GCP Console (див. розділ 11)
|
| 735 |
+
2. Використовуйте доступну модель: `gemini-2.0-flash`
|
| 736 |
+
3. Перевірте регіон: переконайтеся, що модель доступна у вашому регіоні
|
| 737 |
+
|
| 738 |
+
### 12.5 Помилка: "Permission denied"
|
| 739 |
+
|
| 740 |
+
**Рішення:**
|
| 741 |
+
```python
|
| 742 |
+
# Перевірити credentials
|
| 743 |
+
from google.oauth2 import service_account
|
| 744 |
+
|
| 745 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 746 |
+
service_account_dict,
|
| 747 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 748 |
+
)
|
| 749 |
+
|
| 750 |
+
# Переконатися, що service account має необхідні ролі:
|
| 751 |
+
# - Vertex AI User
|
| 752 |
+
# - Vertex AI Service Agent
|
| 753 |
+
```
|
| 754 |
+
|
| 755 |
+
---
|
| 756 |
+
|
| 757 |
+
## 13. Посилання та Ресурси
|
| 758 |
+
|
| 759 |
+
- [Google Generative AI Python SDK](https://github.com/google/generative-ai-python)
|
| 760 |
+
- [Vertex AI Generative AI Documentation](https://cloud.google.com/vertex-ai/generative-ai/docs)
|
| 761 |
+
- [GCP Service Account Setup](https://cloud.google.com/docs/authentication/getting-started)
|
| 762 |
+
- [Python dotenv Documentation](https://github.com/theskumar/python-dotenv)
|
| 763 |
+
|
| 764 |
+
---
|
check_available_models.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Перевірка доступних моделей у Vertex AI
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import base64
|
| 8 |
+
import json
|
| 9 |
+
import logging
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
+
|
| 12 |
+
logging.basicConfig(
|
| 13 |
+
level=logging.INFO,
|
| 14 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 15 |
+
)
|
| 16 |
+
logger = logging.getLogger(__name__)
|
| 17 |
+
|
| 18 |
+
load_dotenv()
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def get_available_models():
|
| 22 |
+
"""Отримати список доступних моделей"""
|
| 23 |
+
|
| 24 |
+
try:
|
| 25 |
+
from google.oauth2 import service_account
|
| 26 |
+
import vertexai
|
| 27 |
+
from vertexai.generative_models import GenerativeModel
|
| 28 |
+
|
| 29 |
+
# Отримати credentials
|
| 30 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 31 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 32 |
+
service_account_dict = json.loads(service_account_json)
|
| 33 |
+
|
| 34 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 35 |
+
service_account_dict,
|
| 36 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 37 |
+
)
|
| 38 |
+
|
| 39 |
+
project_id = service_account_dict.get('project_id')
|
| 40 |
+
|
| 41 |
+
# Ініціалізація Vertex AI
|
| 42 |
+
vertexai.init(project=project_id, credentials=credentials)
|
| 43 |
+
|
| 44 |
+
logger.info("=" * 70)
|
| 45 |
+
logger.info("ДОСТУПНІ МОДЕЛІ GEMINI У VERTEX AI")
|
| 46 |
+
logger.info("=" * 70)
|
| 47 |
+
|
| 48 |
+
# Список моделей для перевірки
|
| 49 |
+
models_to_check = [
|
| 50 |
+
"gemini-3-flash-preview",
|
| 51 |
+
"gemini-3-flash",
|
| 52 |
+
"gemini-2.0-flash-preview",
|
| 53 |
+
"gemini-2.0-flash",
|
| 54 |
+
"gemini-1.5-pro",
|
| 55 |
+
"gemini-1.5-flash",
|
| 56 |
+
"gemini-pro",
|
| 57 |
+
]
|
| 58 |
+
|
| 59 |
+
logger.info(f"\nПроект: {project_id}\n")
|
| 60 |
+
logger.info("Перевірка доступності моделей:\n")
|
| 61 |
+
|
| 62 |
+
available_models = []
|
| 63 |
+
|
| 64 |
+
for model_name in models_to_check:
|
| 65 |
+
try:
|
| 66 |
+
model = GenerativeModel(model_name)
|
| 67 |
+
response = model.generate_content("test", stream=False)
|
| 68 |
+
logger.info(f"✓ {model_name:30} - ДОСТУПНА")
|
| 69 |
+
available_models.append(model_name)
|
| 70 |
+
except Exception as e:
|
| 71 |
+
error_msg = str(e)
|
| 72 |
+
if "404" in error_msg or "not found" in error_msg.lower():
|
| 73 |
+
logger.info(f"✗ {model_name:30} - недоступна")
|
| 74 |
+
else:
|
| 75 |
+
logger.info(f"? {model_name:30} - помилка: {error_msg[:50]}")
|
| 76 |
+
|
| 77 |
+
logger.info("\n" + "=" * 70)
|
| 78 |
+
if available_models:
|
| 79 |
+
logger.info(f"ЗНАЙДЕНО {len(available_models)} ДОСТУПНИХ МОДЕЛЕЙ:")
|
| 80 |
+
logger.info("=" * 70)
|
| 81 |
+
for model in available_models:
|
| 82 |
+
logger.info(f" • {model}")
|
| 83 |
+
else:
|
| 84 |
+
logger.warning("ЖОДНА МОДЕЛЬ НЕ ДОСТУПНА")
|
| 85 |
+
logger.info("=" * 70)
|
| 86 |
+
|
| 87 |
+
return available_models
|
| 88 |
+
|
| 89 |
+
except Exception as e:
|
| 90 |
+
logger.error(f"Помилка: {e}")
|
| 91 |
+
return []
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
if __name__ == "__main__":
|
| 95 |
+
get_available_models()
|
check_vertex_ai_access.py
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Перевірка доступності gemini-3-flash-preview через Vertex AI API
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import sys
|
| 8 |
+
import base64
|
| 9 |
+
import json
|
| 10 |
+
import logging
|
| 11 |
+
from dotenv import load_dotenv
|
| 12 |
+
|
| 13 |
+
# Налаштування логування
|
| 14 |
+
logging.basicConfig(
|
| 15 |
+
level=logging.INFO,
|
| 16 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 17 |
+
)
|
| 18 |
+
logger = logging.getLogger(__name__)
|
| 19 |
+
|
| 20 |
+
# Завантажити змінні середовища
|
| 21 |
+
load_dotenv()
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def check_vertex_ai_access():
|
| 25 |
+
"""
|
| 26 |
+
Перевірка доступності gemini-3-flash-preview через Vertex AI API
|
| 27 |
+
|
| 28 |
+
Returns:
|
| 29 |
+
dict: Результати перевірки
|
| 30 |
+
"""
|
| 31 |
+
|
| 32 |
+
results = {
|
| 33 |
+
'status': 'failed',
|
| 34 |
+
'checks': {},
|
| 35 |
+
'error': None
|
| 36 |
+
}
|
| 37 |
+
|
| 38 |
+
try:
|
| 39 |
+
# Перевірка 1: Наявність GCP_SERVICE_ACCOUNT_B64
|
| 40 |
+
logger.info("=" * 60)
|
| 41 |
+
logger.info("Перевірка 1: Наявність GCP_SERVICE_ACCOUNT_B64")
|
| 42 |
+
logger.info("=" * 60)
|
| 43 |
+
|
| 44 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 45 |
+
if not service_account_b64:
|
| 46 |
+
raise ValueError("GCP_SERVICE_ACCOUNT_B64 не знайдено в .env")
|
| 47 |
+
|
| 48 |
+
logger.info("✓ GCP_SERVICE_ACCOUNT_B64 знайдено")
|
| 49 |
+
results['checks']['service_account_b64'] = True
|
| 50 |
+
|
| 51 |
+
# Перевірка 2: Декодування Base64
|
| 52 |
+
logger.info("\n" + "=" * 60)
|
| 53 |
+
logger.info("Перевірка 2: Декодування Base64 Service Account")
|
| 54 |
+
logger.info("=" * 60)
|
| 55 |
+
|
| 56 |
+
try:
|
| 57 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 58 |
+
service_account_dict = json.loads(service_account_json)
|
| 59 |
+
logger.info("✓ Base64 успішно декодовано")
|
| 60 |
+
results['checks']['base64_decode'] = True
|
| 61 |
+
except Exception as e:
|
| 62 |
+
raise ValueError(f"Помилка декодування Base64: {e}")
|
| 63 |
+
|
| 64 |
+
# Перевірка 3: Валідація Service Account структури
|
| 65 |
+
logger.info("\n" + "=" * 60)
|
| 66 |
+
logger.info("Перевірка 3: Валідація Service Account структури")
|
| 67 |
+
logger.info("=" * 60)
|
| 68 |
+
|
| 69 |
+
required_fields = ['type', 'project_id', 'private_key', 'client_email']
|
| 70 |
+
for field in required_fields:
|
| 71 |
+
if field not in service_account_dict:
|
| 72 |
+
raise ValueError(f"Поле '{field}' відсутнє в service account")
|
| 73 |
+
|
| 74 |
+
project_id = service_account_dict.get('project_id')
|
| 75 |
+
client_email = service_account_dict.get('client_email')
|
| 76 |
+
|
| 77 |
+
logger.info(f"✓ Project ID: {project_id}")
|
| 78 |
+
logger.info(f"✓ Client Email: {client_email}")
|
| 79 |
+
results['checks']['service_account_structure'] = True
|
| 80 |
+
results['project_id'] = project_id
|
| 81 |
+
results['client_email'] = client_email
|
| 82 |
+
|
| 83 |
+
# Перевірка 4: Імпорт Google Cloud бібліотек
|
| 84 |
+
logger.info("\n" + "=" * 60)
|
| 85 |
+
logger.info("Перевірка 4: Імпорт Google Cloud бібліотек")
|
| 86 |
+
logger.info("=" * 60)
|
| 87 |
+
|
| 88 |
+
try:
|
| 89 |
+
from google.oauth2 import service_account
|
| 90 |
+
from google.auth.transport.requests import Request
|
| 91 |
+
import google.generativeai as genai
|
| 92 |
+
from vertexai.generative_models import GenerativeModel
|
| 93 |
+
|
| 94 |
+
logger.info("✓ google-auth успішно імпортовано")
|
| 95 |
+
logger.info("✓ google-generativeai успішно імпортовано")
|
| 96 |
+
logger.info("✓ vertexai успішно імпортовано")
|
| 97 |
+
results['checks']['imports'] = True
|
| 98 |
+
except ImportError as e:
|
| 99 |
+
raise ImportError(f"Помилка імпорту: {e}")
|
| 100 |
+
|
| 101 |
+
# Перевірка 5: Створення credentials
|
| 102 |
+
logger.info("\n" + "=" * 60)
|
| 103 |
+
logger.info("Перевірка 5: Створення GCP credentials")
|
| 104 |
+
logger.info("=" * 60)
|
| 105 |
+
|
| 106 |
+
try:
|
| 107 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 108 |
+
service_account_dict,
|
| 109 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 110 |
+
)
|
| 111 |
+
logger.info("✓ Credentials успішно створено")
|
| 112 |
+
results['checks']['credentials_creation'] = True
|
| 113 |
+
except Exception as e:
|
| 114 |
+
raise Exception(f"Помилка створення credentials: {e}")
|
| 115 |
+
|
| 116 |
+
# Перевірка 6: Тестовий запит до Vertex AI API
|
| 117 |
+
logger.info("\n" + "=" * 60)
|
| 118 |
+
logger.info("Перевірка 6: Тестовий запит до Vertex AI API")
|
| 119 |
+
logger.info("=" * 60)
|
| 120 |
+
|
| 121 |
+
try:
|
| 122 |
+
import vertexai
|
| 123 |
+
|
| 124 |
+
# Ініціалізація Vertex AI
|
| 125 |
+
vertexai.init(project=project_id, credentials=credentials)
|
| 126 |
+
logger.info(f"✓ Vertex AI ініціалізовано для проекту: {project_id}")
|
| 127 |
+
|
| 128 |
+
# Спроба створити модель
|
| 129 |
+
model = GenerativeModel("gemini-3-flash-preview")
|
| 130 |
+
logger.info("✓ Модель gemini-3-flash-preview успішно завантажена")
|
| 131 |
+
results['checks']['model_loading'] = True
|
| 132 |
+
|
| 133 |
+
# Тестовий запит
|
| 134 |
+
logger.info("\n📤 Відправлення тестового запиту...")
|
| 135 |
+
response = model.generate_content("Привіт! Скажи мені одне слово.")
|
| 136 |
+
|
| 137 |
+
if response and response.text:
|
| 138 |
+
logger.info("✓ Тестовий запит успішний!")
|
| 139 |
+
logger.info(f"📥 Відповідь: {response.text[:100]}...")
|
| 140 |
+
results['checks']['test_request'] = True
|
| 141 |
+
results['test_response'] = response.text[:200]
|
| 142 |
+
else:
|
| 143 |
+
raise Exception("Порожня відповідь від моделі")
|
| 144 |
+
|
| 145 |
+
except Exception as e:
|
| 146 |
+
logger.error(f"✗ Помилка при запиті до Vertex AI: {e}")
|
| 147 |
+
results['checks']['test_request'] = False
|
| 148 |
+
results['error'] = str(e)
|
| 149 |
+
raise
|
| 150 |
+
|
| 151 |
+
# Перевірка 7: Інформація про модель
|
| 152 |
+
logger.info("\n" + "=" * 60)
|
| 153 |
+
logger.info("Перевірка 7: Інформація про модель")
|
| 154 |
+
logger.info("=" * 60)
|
| 155 |
+
|
| 156 |
+
try:
|
| 157 |
+
logger.info(f"Модель: gemini-3-flash-preview")
|
| 158 |
+
logger.info(f"Платформа: Vertex AI")
|
| 159 |
+
logger.info(f"Проект: {project_id}")
|
| 160 |
+
results['checks']['model_info'] = True
|
| 161 |
+
except Exception as e:
|
| 162 |
+
logger.error(f"Помилка отримання інформації: {e}")
|
| 163 |
+
|
| 164 |
+
# Успіх!
|
| 165 |
+
results['status'] = 'success'
|
| 166 |
+
|
| 167 |
+
except Exception as e:
|
| 168 |
+
logger.error(f"\n✗ Критична помилка: {e}")
|
| 169 |
+
results['error'] = str(e)
|
| 170 |
+
results['status'] = 'failed'
|
| 171 |
+
|
| 172 |
+
return results
|
| 173 |
+
|
| 174 |
+
|
| 175 |
+
def print_summary(results):
|
| 176 |
+
"""Вивести підсумок результатів"""
|
| 177 |
+
|
| 178 |
+
logger.info("\n" + "=" * 60)
|
| 179 |
+
logger.info("ПІДСУМОК ПЕРЕВІРКИ")
|
| 180 |
+
logger.info("=" * 60)
|
| 181 |
+
|
| 182 |
+
if results['status'] == 'success':
|
| 183 |
+
logger.info("✓ ВСІ ПЕРЕВІРКИ ПРОЙДЕНІ УСПІШНО!")
|
| 184 |
+
logger.info(f"\nПроект: {results.get('project_id', 'N/A')}")
|
| 185 |
+
logger.info(f"Email: {results.get('client_email', 'N/A')}")
|
| 186 |
+
logger.info(f"\nМодель gemini-3-flash-preview доступна через Vertex AI API")
|
| 187 |
+
logger.info(f"\nТестова відповідь: {results.get('test_response', 'N/A')}")
|
| 188 |
+
else:
|
| 189 |
+
logger.error("✗ ПЕРЕВІРКА НЕ ПРОЙДЕНА")
|
| 190 |
+
logger.error(f"Помилка: {results.get('error', 'Невідома помилка')}")
|
| 191 |
+
|
| 192 |
+
logger.info("\n" + "=" * 60)
|
| 193 |
+
logger.info("ДЕТАЛІ ПЕРЕВІРОК:")
|
| 194 |
+
logger.info("=" * 60)
|
| 195 |
+
|
| 196 |
+
checks = results.get('checks', {})
|
| 197 |
+
for check_name, check_result in checks.items():
|
| 198 |
+
status = "✓" if check_result else "✗"
|
| 199 |
+
logger.info(f"{status} {check_name}: {'Пройдено' if check_result else 'Не пройдено'}")
|
| 200 |
+
|
| 201 |
+
logger.info("=" * 60)
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
if __name__ == "__main__":
|
| 205 |
+
try:
|
| 206 |
+
results = check_vertex_ai_access()
|
| 207 |
+
print_summary(results)
|
| 208 |
+
|
| 209 |
+
# Вихід з кодом помилки якщо перевірка не пройдена
|
| 210 |
+
sys.exit(0 if results['status'] == 'success' else 1)
|
| 211 |
+
|
| 212 |
+
except KeyboardInterrupt:
|
| 213 |
+
logger.info("\n\nПеревірка перервана користувачем")
|
| 214 |
+
sys.exit(1)
|
| 215 |
+
except Exception as e:
|
| 216 |
+
logger.error(f"Невідома помилка: {e}")
|
| 217 |
+
sys.exit(1)
|
fix_vertex_ai_config.py
ADDED
|
@@ -0,0 +1,287 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""
|
| 3 |
+
Виправлення конфігурації Vertex AI згідно з рекомендаціями Google Cloud
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
import os
|
| 7 |
+
import base64
|
| 8 |
+
import json
|
| 9 |
+
import logging
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
+
|
| 12 |
+
logging.basicConfig(
|
| 13 |
+
level=logging.INFO,
|
| 14 |
+
format='%(asctime)s - %(levelname)s - %(message)s'
|
| 15 |
+
)
|
| 16 |
+
logger = logging.getLogger(__name__)
|
| 17 |
+
|
| 18 |
+
load_dotenv()
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
def check_vertex_ai_config():
|
| 22 |
+
"""
|
| 23 |
+
Комплексна перевірка конфігурації Vertex AI
|
| 24 |
+
"""
|
| 25 |
+
|
| 26 |
+
results = {
|
| 27 |
+
'status': 'failed',
|
| 28 |
+
'checks': {},
|
| 29 |
+
'recommendations': [],
|
| 30 |
+
'available_models': []
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
try:
|
| 34 |
+
logger.info("=" * 80)
|
| 35 |
+
logger.info("КОМПЛЕКСНА ПЕРЕВІРКА КОНФІГУРАЦІЇ VERTEX AI")
|
| 36 |
+
logger.info("=" * 80)
|
| 37 |
+
|
| 38 |
+
# 1. Перевірка Service Account
|
| 39 |
+
logger.info("\n1. ПЕРЕВІРКА SERVICE ACCOUNT")
|
| 40 |
+
logger.info("-" * 50)
|
| 41 |
+
|
| 42 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 43 |
+
if not service_account_b64:
|
| 44 |
+
raise ValueError("GCP_SERVICE_ACCOUNT_B64 не знайдено в .env")
|
| 45 |
+
|
| 46 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 47 |
+
service_account_dict = json.loads(service_account_json)
|
| 48 |
+
|
| 49 |
+
project_id = service_account_dict.get('project_id')
|
| 50 |
+
client_email = service_account_dict.get('client_email')
|
| 51 |
+
|
| 52 |
+
logger.info(f"✓ Project ID: {project_id}")
|
| 53 |
+
logger.info(f"✓ Client Email: {client_email}")
|
| 54 |
+
results['checks']['service_account'] = True
|
| 55 |
+
|
| 56 |
+
# 2. Перевірка регіону
|
| 57 |
+
logger.info("\n2. ПЕРЕВІРКА РЕГІОНУ")
|
| 58 |
+
logger.info("-" * 50)
|
| 59 |
+
|
| 60 |
+
# Популярні регіони для Gemini
|
| 61 |
+
supported_regions = [
|
| 62 |
+
'us-central1', 'us-east1', 'us-west1', 'us-west4',
|
| 63 |
+
'europe-west1', 'europe-west2', 'europe-west4',
|
| 64 |
+
'asia-northeast1', 'asia-southeast1'
|
| 65 |
+
]
|
| 66 |
+
|
| 67 |
+
current_region = 'us-central1' # За замовчуванням
|
| 68 |
+
logger.info(f"✓ Поточний регіон: {current_region}")
|
| 69 |
+
logger.info(f"✓ Підтримувані регіони: {', '.join(supported_regions[:5])}...")
|
| 70 |
+
results['checks']['region'] = True
|
| 71 |
+
|
| 72 |
+
# 3. Перевірка актуальних моделей
|
| 73 |
+
logger.info("\n3. ПЕРЕВІРКА АКТУАЛЬНИХ МОДЕЛЕЙ")
|
| 74 |
+
logger.info("-" * 50)
|
| 75 |
+
|
| 76 |
+
# Актуальні моделі станом на 2025
|
| 77 |
+
current_models = [
|
| 78 |
+
"gemini-2.0-flash",
|
| 79 |
+
"gemini-2.0-flash-exp",
|
| 80 |
+
"gemini-1.5-pro",
|
| 81 |
+
"gemini-1.5-flash",
|
| 82 |
+
"gemini-1.0-pro"
|
| 83 |
+
]
|
| 84 |
+
|
| 85 |
+
deprecated_models = [
|
| 86 |
+
"gemini-3-flash-preview",
|
| 87 |
+
"gemini-3-flash",
|
| 88 |
+
"gemini-2.0-flash-preview"
|
| 89 |
+
]
|
| 90 |
+
|
| 91 |
+
logger.info("Перевірка актуальних моделей:")
|
| 92 |
+
|
| 93 |
+
from google.oauth2 import service_account
|
| 94 |
+
import vertexai
|
| 95 |
+
from vertexai.generative_models import GenerativeModel
|
| 96 |
+
|
| 97 |
+
# Створення credentials
|
| 98 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 99 |
+
service_account_dict,
|
| 100 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 101 |
+
)
|
| 102 |
+
|
| 103 |
+
# Ініціалізація Vertex AI
|
| 104 |
+
vertexai.init(project=project_id, credentials=credentials, location=current_region)
|
| 105 |
+
|
| 106 |
+
available_models = []
|
| 107 |
+
|
| 108 |
+
for model_name in current_models:
|
| 109 |
+
try:
|
| 110 |
+
model = GenerativeModel(model_name)
|
| 111 |
+
response = model.generate_content("test", stream=False)
|
| 112 |
+
logger.info(f"✓ {model_name:25} - ДОСТУПНА")
|
| 113 |
+
available_models.append(model_name)
|
| 114 |
+
results['available_models'].append(model_name)
|
| 115 |
+
except Exception as e:
|
| 116 |
+
error_msg = str(e)
|
| 117 |
+
if "404" in error_msg:
|
| 118 |
+
logger.info(f"✗ {model_name:25} - недоступна")
|
| 119 |
+
else:
|
| 120 |
+
logger.info(f"? {model_name:25} - помилка доступу")
|
| 121 |
+
|
| 122 |
+
# 4. Перевірка застарілих моделей
|
| 123 |
+
logger.info("\nПеревірка застарілих моделей:")
|
| 124 |
+
for model_name in deprecated_models:
|
| 125 |
+
logger.info(f"⚠ {model_name:25} - ЗАСТАРІЛА (використовуйте {current_models[0]})")
|
| 126 |
+
results['recommendations'].append(f"Замініть {model_name} на {current_models[0]}")
|
| 127 |
+
|
| 128 |
+
# 5. Генерація рекомендацій
|
| 129 |
+
logger.info("\n4. РЕКОМЕНДАЦІЇ")
|
| 130 |
+
logger.info("-" * 50)
|
| 131 |
+
|
| 132 |
+
if available_models:
|
| 133 |
+
logger.info("✓ З��айдено доступні моделі:")
|
| 134 |
+
for model in available_models:
|
| 135 |
+
logger.info(f" • Використовуйте: {model}")
|
| 136 |
+
|
| 137 |
+
# Рекомендована модель
|
| 138 |
+
recommended_model = available_models[0]
|
| 139 |
+
logger.info(f"\n🎯 РЕКОМЕНДОВАНА МОДЕЛЬ: {recommended_model}")
|
| 140 |
+
results['recommended_model'] = recommended_model
|
| 141 |
+
|
| 142 |
+
# Приклад коду
|
| 143 |
+
logger.info("\n📝 ПРИКЛАД КОДУ:")
|
| 144 |
+
logger.info("```python")
|
| 145 |
+
logger.info("from vertexai.generative_models import GenerativeModel")
|
| 146 |
+
logger.info("import vertexai")
|
| 147 |
+
logger.info("")
|
| 148 |
+
logger.info(f"# Ініціалізація з правильною моделлю")
|
| 149 |
+
logger.info(f"vertexai.init(project='{project_id}', location='us-central1')")
|
| 150 |
+
logger.info(f"model = GenerativeModel('{recommended_model}')")
|
| 151 |
+
logger.info("response = model.generate_content('Ваш запит')")
|
| 152 |
+
logger.info("```")
|
| 153 |
+
|
| 154 |
+
else:
|
| 155 |
+
logger.warning("⚠ Жодна модель не доступна")
|
| 156 |
+
results['recommendations'].append("Перевірте IAM ролі та доступ до Vertex AI")
|
| 157 |
+
|
| 158 |
+
# 6. Перевірка IAM прав
|
| 159 |
+
logger.info("\n5. ПЕРЕВІРКА IAM ПРАВ")
|
| 160 |
+
logger.info("-" * 50)
|
| 161 |
+
|
| 162 |
+
logger.info("Необхідні ролі для Service Account:")
|
| 163 |
+
logger.info("• Vertex AI User (roles/aiplatform.user)")
|
| 164 |
+
logger.info("• Vertex AI Service Agent (roles/aiplatform.serviceAgent)")
|
| 165 |
+
logger.info(f"• Перевірте роль для: {client_email}")
|
| 166 |
+
|
| 167 |
+
results['checks']['iam_info'] = True
|
| 168 |
+
|
| 169 |
+
# 7. Фінальний статус
|
| 170 |
+
if available_models:
|
| 171 |
+
results['status'] = 'success'
|
| 172 |
+
logger.info("\n✅ КОНФІГУРАЦІЯ ВЕРНА")
|
| 173 |
+
else:
|
| 174 |
+
logger.info("\n❌ ПОТРІБНЕ НАЛАШТУВАННЯ ДОСТУПУ")
|
| 175 |
+
|
| 176 |
+
except Exception as e:
|
| 177 |
+
logger.error(f"Помилка перевірки: {e}")
|
| 178 |
+
results['error'] = str(e)
|
| 179 |
+
|
| 180 |
+
return results
|
| 181 |
+
|
| 182 |
+
|
| 183 |
+
def generate_fixed_config():
|
| 184 |
+
"""
|
| 185 |
+
Генерація виправленої конфігурації
|
| 186 |
+
"""
|
| 187 |
+
|
| 188 |
+
logger.info("\n" + "=" * 80)
|
| 189 |
+
logger.info("ГЕНЕРАЦІЯ ВИПРАВЛЕНОЇ КОНФІГУРАЦІЇ")
|
| 190 |
+
logger.info("=" * 80)
|
| 191 |
+
|
| 192 |
+
config_code = '''
|
| 193 |
+
# ВИПРАВЛЕНА КОНФІГУРАЦІЯ VERTEX AI
|
| 194 |
+
# Створено на основі рекомендацій Google Cloud
|
| 195 |
+
|
| 196 |
+
import os
|
| 197 |
+
import base64
|
| 198 |
+
import json
|
| 199 |
+
from dotenv import load_dotenv
|
| 200 |
+
from google.oauth2 import service_account
|
| 201 |
+
import vertexai
|
| 202 |
+
from vertexai.generative_models import GenerativeModel
|
| 203 |
+
|
| 204 |
+
# Завантаження змінних середовища
|
| 205 |
+
load_dotenv()
|
| 206 |
+
|
| 207 |
+
def setup_vertex_ai():
|
| 208 |
+
"""
|
| 209 |
+
Правильна налаштування Vertex AI
|
| 210 |
+
"""
|
| 211 |
+
|
| 212 |
+
# Отримання Service Account
|
| 213 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 214 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 215 |
+
service_account_dict = json.loads(service_account_json)
|
| 216 |
+
|
| 217 |
+
# Створення credentials
|
| 218 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 219 |
+
service_account_dict,
|
| 220 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 221 |
+
)
|
| 222 |
+
|
| 223 |
+
# Ініціалізація з правильним регіоном
|
| 224 |
+
project_id = service_account_dict.get('project_id')
|
| 225 |
+
vertexai.init(
|
| 226 |
+
project=project_id,
|
| 227 |
+
credentials=credentials,
|
| 228 |
+
location='us-central1' # Підтримуваний регіон
|
| 229 |
+
)
|
| 230 |
+
|
| 231 |
+
return project_id
|
| 232 |
+
|
| 233 |
+
def create_gemini_client():
|
| 234 |
+
"""
|
| 235 |
+
Створення клієнта з правильною моделлю
|
| 236 |
+
"""
|
| 237 |
+
|
| 238 |
+
project_id = setup_vertex_ai()
|
| 239 |
+
|
| 240 |
+
# Використання доступної моделі
|
| 241 |
+
model_name = "gemini-2.0-flash" # Перевірено як доступна
|
| 242 |
+
|
| 243 |
+
model = GenerativeModel(model_name)
|
| 244 |
+
|
| 245 |
+
return model, model_name
|
| 246 |
+
|
| 247 |
+
# Приклад використання
|
| 248 |
+
if __name__ == "__main__":
|
| 249 |
+
try:
|
| 250 |
+
model, model_name = create_gemini_client()
|
| 251 |
+
|
| 252 |
+
print(f"✅ Модель {model_name} успішно ініціалізована")
|
| 253 |
+
|
| 254 |
+
# Тестовий запит
|
| 255 |
+
response = model.generate_content("Привіт! Як справи?")
|
| 256 |
+
print(f"📥 Відповідь: {response.text}")
|
| 257 |
+
|
| 258 |
+
except Exception as e:
|
| 259 |
+
print(f"❌ Помилка: {e}")
|
| 260 |
+
'''
|
| 261 |
+
|
| 262 |
+
# Збереження виправленої конфігурації
|
| 263 |
+
with open('/Users/serhiizabolotnii/Medical Brain/Lifestyle/vertex_ai_fixed_config.py', 'w', encoding='utf-8') as f:
|
| 264 |
+
f.write(config_code)
|
| 265 |
+
|
| 266 |
+
logger.info("✅ Виправлену конфігурацію збережено: vertex_ai_fixed_config.py")
|
| 267 |
+
logger.info("\n📋 НАСТУПНІ КРОКИ:")
|
| 268 |
+
logger.info("1. Використовуйте модель 'gemini-2.0-flash'")
|
| 269 |
+
logger.info("2. Переконайтеся що регіон 'us-central1' підтримується")
|
| 270 |
+
logger.info("3. Перевірте IAM ролі для Service Account")
|
| 271 |
+
logger.info("4. Замініть застарілі моделі в коді")
|
| 272 |
+
|
| 273 |
+
|
| 274 |
+
if __name__ == "__main__":
|
| 275 |
+
results = check_vertex_ai_config()
|
| 276 |
+
generate_fixed_config()
|
| 277 |
+
|
| 278 |
+
logger.info("\n" + "=" * 80)
|
| 279 |
+
logger.info("ПІДСУМОК")
|
| 280 |
+
logger.info("=" * 80)
|
| 281 |
+
|
| 282 |
+
if results['status'] == 'success':
|
| 283 |
+
logger.info("✅ Конфігурація Vertex AI виправлена")
|
| 284 |
+
logger.info(f"🎯 Рекомендована модель: {results.get('recommended_model', 'N/A')}")
|
| 285 |
+
else:
|
| 286 |
+
logger.info("❌ Потрібне додаткове налаштування доступу")
|
| 287 |
+
logger.info("Перевірте IAM ролі та доступ до Vertex AI")
|
vertex_ai_fixed_config.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
|
| 2 |
+
# ВИПРАВЛЕНА КОНФІГУРАЦІЯ VERTEX AI
|
| 3 |
+
# Створено на основі рекомендацій Google Cloud
|
| 4 |
+
|
| 5 |
+
import os
|
| 6 |
+
import base64
|
| 7 |
+
import json
|
| 8 |
+
from dotenv import load_dotenv
|
| 9 |
+
from google.oauth2 import service_account
|
| 10 |
+
import vertexai
|
| 11 |
+
from vertexai.generative_models import GenerativeModel
|
| 12 |
+
|
| 13 |
+
# Завантаження змінних середовища
|
| 14 |
+
load_dotenv()
|
| 15 |
+
|
| 16 |
+
def setup_vertex_ai():
|
| 17 |
+
"""
|
| 18 |
+
Правильна налаштування Vertex AI
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
# Отримання Service Account
|
| 22 |
+
service_account_b64 = os.getenv('GCP_SERVICE_ACCOUNT_B64')
|
| 23 |
+
service_account_json = base64.b64decode(service_account_b64).decode('utf-8')
|
| 24 |
+
service_account_dict = json.loads(service_account_json)
|
| 25 |
+
|
| 26 |
+
# Створення credentials
|
| 27 |
+
credentials = service_account.Credentials.from_service_account_info(
|
| 28 |
+
service_account_dict,
|
| 29 |
+
scopes=['https://www.googleapis.com/auth/cloud-platform']
|
| 30 |
+
)
|
| 31 |
+
|
| 32 |
+
# Ініціалізація з правильним регіоном
|
| 33 |
+
project_id = service_account_dict.get('project_id')
|
| 34 |
+
vertexai.init(
|
| 35 |
+
project=project_id,
|
| 36 |
+
credentials=credentials,
|
| 37 |
+
location='us-central1' # Підтримуваний регіон
|
| 38 |
+
)
|
| 39 |
+
|
| 40 |
+
return project_id
|
| 41 |
+
|
| 42 |
+
def create_gemini_client():
|
| 43 |
+
"""
|
| 44 |
+
Створення клієнта з правильною моделлю
|
| 45 |
+
"""
|
| 46 |
+
|
| 47 |
+
project_id = setup_vertex_ai()
|
| 48 |
+
|
| 49 |
+
# Використання доступної моделі
|
| 50 |
+
model_name = "gemini-2.0-flash" # Перевірено як доступна
|
| 51 |
+
|
| 52 |
+
model = GenerativeModel(model_name)
|
| 53 |
+
|
| 54 |
+
return model, model_name
|
| 55 |
+
|
| 56 |
+
# Приклад використання
|
| 57 |
+
if __name__ == "__main__":
|
| 58 |
+
try:
|
| 59 |
+
model, model_name = create_gemini_client()
|
| 60 |
+
|
| 61 |
+
print(f"✅ Модель {model_name} успішно ініціалізована")
|
| 62 |
+
|
| 63 |
+
# Тестовий запит
|
| 64 |
+
response = model.generate_content("Привіт! Як справи?")
|
| 65 |
+
print(f"📥 Відповідь: {response.text}")
|
| 66 |
+
|
| 67 |
+
except Exception as e:
|
| 68 |
+
print(f"❌ Помилка: {e}")
|