Spaces:
Sleeping
Sleeping
Add binary architecture compatibility check and better error handling
Browse files
llm_clients/qwen_translator.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
from typing import Generator, Any, Dict
|
| 2 |
import os
|
| 3 |
import sys
|
|
|
|
| 4 |
import subprocess
|
| 5 |
import tempfile
|
| 6 |
import zipfile
|
|
@@ -59,7 +60,19 @@ class QwenTranslatorClient(LlmClient):
|
|
| 59 |
)
|
| 60 |
|
| 61 |
if cls._binary_path and os.path.exists(cls._binary_path):
|
| 62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
print("📥 Downloading pre-built llama.cpp binary...")
|
| 65 |
|
|
@@ -157,7 +170,7 @@ class QwenTranslatorClient(LlmClient):
|
|
| 157 |
try:
|
| 158 |
os.chmod(found_binary, 0o755)
|
| 159 |
except Exception as chmod_error:
|
| 160 |
-
print(f" ⚠️ Warning: Could not set executable permissions: {chmod_error}")
|
| 161 |
|
| 162 |
# Move to expected location if needed (use 'main' as standard name)
|
| 163 |
if found_binary != binary_path:
|
|
@@ -166,15 +179,68 @@ class QwenTranslatorClient(LlmClient):
|
|
| 166 |
shutil.move(str(found_binary), str(binary_path))
|
| 167 |
|
| 168 |
cls._binary_path = str(binary_path)
|
| 169 |
-
print(f" ✅ Binary extracted and ready at: {cls._binary_path}")
|
| 170 |
|
| 171 |
-
# Verify binary is executable
|
| 172 |
if not os.access(cls._binary_path, os.X_OK):
|
| 173 |
-
print(f" ⚠️ Warning: Binary may not be executable. Attempting to fix...")
|
| 174 |
try:
|
| 175 |
os.chmod(cls._binary_path, 0o755)
|
| 176 |
-
except Exception:
|
| 177 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 178 |
|
| 179 |
# Clean up zip file
|
| 180 |
try:
|
|
|
|
| 1 |
from typing import Generator, Any, Dict
|
| 2 |
import os
|
| 3 |
import sys
|
| 4 |
+
import platform
|
| 5 |
import subprocess
|
| 6 |
import tempfile
|
| 7 |
import zipfile
|
|
|
|
| 60 |
)
|
| 61 |
|
| 62 |
if cls._binary_path and os.path.exists(cls._binary_path):
|
| 63 |
+
# Verify it's still executable
|
| 64 |
+
if os.access(cls._binary_path, os.X_OK):
|
| 65 |
+
return cls._binary_path
|
| 66 |
+
else:
|
| 67 |
+
# Try to fix permissions
|
| 68 |
+
try:
|
| 69 |
+
os.chmod(cls._binary_path, 0o755)
|
| 70 |
+
if os.access(cls._binary_path, os.X_OK):
|
| 71 |
+
return cls._binary_path
|
| 72 |
+
except Exception:
|
| 73 |
+
pass
|
| 74 |
+
# If we can't fix it, re-download
|
| 75 |
+
cls._binary_path = None
|
| 76 |
|
| 77 |
print("📥 Downloading pre-built llama.cpp binary...")
|
| 78 |
|
|
|
|
| 170 |
try:
|
| 171 |
os.chmod(found_binary, 0o755)
|
| 172 |
except Exception as chmod_error:
|
| 173 |
+
print(f" ⚠️ Warning: Could not set executable permissions: {chmod_error}", flush=True)
|
| 174 |
|
| 175 |
# Move to expected location if needed (use 'main' as standard name)
|
| 176 |
if found_binary != binary_path:
|
|
|
|
| 179 |
shutil.move(str(found_binary), str(binary_path))
|
| 180 |
|
| 181 |
cls._binary_path = str(binary_path)
|
| 182 |
+
print(f" ✅ Binary extracted and ready at: {cls._binary_path}", flush=True)
|
| 183 |
|
| 184 |
+
# Verify binary is executable and test it
|
| 185 |
if not os.access(cls._binary_path, os.X_OK):
|
| 186 |
+
print(f" ⚠️ Warning: Binary may not be executable. Attempting to fix...", flush=True)
|
| 187 |
try:
|
| 188 |
os.chmod(cls._binary_path, 0o755)
|
| 189 |
+
except Exception as e:
|
| 190 |
+
print(f" ⚠️ Could not set permissions: {e}", flush=True)
|
| 191 |
+
|
| 192 |
+
# Test if binary can actually run (check architecture compatibility)
|
| 193 |
+
print(f" 🔍 Testing binary compatibility...", flush=True)
|
| 194 |
+
machine = platform.machine()
|
| 195 |
+
print(f" System architecture: {machine}", flush=True)
|
| 196 |
+
|
| 197 |
+
try:
|
| 198 |
+
# Try to run the binary with --help to verify it works
|
| 199 |
+
test_result = subprocess.run(
|
| 200 |
+
[cls._binary_path, "--help"],
|
| 201 |
+
capture_output=True,
|
| 202 |
+
text=True,
|
| 203 |
+
timeout=5
|
| 204 |
+
)
|
| 205 |
+
if test_result.returncode == 0 or "usage" in test_result.stdout.lower() or "options" in test_result.stdout.lower():
|
| 206 |
+
print(f" ✅ Binary is compatible and executable", flush=True)
|
| 207 |
+
else:
|
| 208 |
+
print(f" ⚠️ Binary test returned code {test_result.returncode}", flush=True)
|
| 209 |
+
if test_result.stderr:
|
| 210 |
+
print(f" Stderr: {test_result.stderr[:200]}", flush=True)
|
| 211 |
+
except subprocess.TimeoutExpired:
|
| 212 |
+
print(f" ⚠️ Binary test timed out", flush=True)
|
| 213 |
+
except OSError as os_error:
|
| 214 |
+
error_msg = str(os_error)
|
| 215 |
+
errno = getattr(os_error, 'errno', None)
|
| 216 |
+
if errno == 8 or "Exec format error" in error_msg or "cannot execute" in error_msg.lower():
|
| 217 |
+
# Check what the binary actually is using 'file' command if available
|
| 218 |
+
file_info = "unknown"
|
| 219 |
+
try:
|
| 220 |
+
file_result = subprocess.run(
|
| 221 |
+
["file", cls._binary_path],
|
| 222 |
+
capture_output=True,
|
| 223 |
+
text=True,
|
| 224 |
+
timeout=2
|
| 225 |
+
)
|
| 226 |
+
if file_result.returncode == 0:
|
| 227 |
+
file_info = file_result.stdout.strip()
|
| 228 |
+
except (subprocess.TimeoutExpired, FileNotFoundError, Exception):
|
| 229 |
+
pass
|
| 230 |
+
|
| 231 |
+
raise RuntimeError(
|
| 232 |
+
f"Binary architecture mismatch. The downloaded binary is not compatible with this system.\n"
|
| 233 |
+
f"System architecture: {machine}\n"
|
| 234 |
+
f"Binary info: {file_info}\n"
|
| 235 |
+
f"Error: {error_msg}\n"
|
| 236 |
+
f"The Ubuntu x64 binary may not be compatible with this system. "
|
| 237 |
+
f"Translation feature requires a compatible llama.cpp binary for this architecture."
|
| 238 |
+
) from os_error
|
| 239 |
+
else:
|
| 240 |
+
raise
|
| 241 |
+
except Exception as test_error:
|
| 242 |
+
error_msg = str(test_error)
|
| 243 |
+
print(f" ⚠️ Binary test warning: {test_error}", flush=True)
|
| 244 |
|
| 245 |
# Clean up zip file
|
| 246 |
try:
|