
Привет! Я Антон, инженер по информационной безопасности в Selectel. В конце сентября Alibaba выпустила три новые модели Qwen3 — MAX, VL и Coder. На бумаге они выглядят впечатляюще: триллион параметров, миллион токенов контекста и результаты на уровне GPT-5. А главное — они бесплатны и доступны из России без ограничений. В тексте проведем честный тест: как Qwen3 справляется с задачами на рассуждение, генерацией кода и работой с интерфейсами. Сравним с ChatGPT и посмотрим, где китайская линейка уже догнала конкурента, а где еще буксует.
Используйте навигацию, если не хотите читать текст полностью:
Qwen3-MAX
Начнем сравнение с Qwen3-MAX — самой крупной модели Alibaba.
Характеристики:
параметров — 1 трлн;
датасет — 36 трлн токенов;
контекст — до 1 млн токенов (примерно 750 тыс. слов);
фокус — сложные рассуждения, математика, программирование.
В особенности привлекли внимание заявленные 100% в бенчмарках AIME25 и HMMT25, поэтому я решил проверить модель по задачам AIME с официального сайта. Прогоняем через Qwen-MAX шесть задач, результат — все ответы правильные. Решения не всегда совпадают с официальными, а вычисления иногда времязатратны, однако ход рассуждений корректный. Самая простая задача заняла около 30 секунд — разберем ее решение.
Проблема (задача):
Find the sum of all positive integers n such that n + 2 divides the product 3(n + 3)(n2+9).

Qwen
Решение
Step 1: Let d = n + 2
Then n = d − 2, and since n > 0, we have d > 2 .
We want:
d | 3((d − 2) + 3)((d − 2)2 + 9) = 3(d + 1)((d − 2)2 + 9)
Compute (d − 2)2 + 9 = d2 − 4d + 4 + 9= d2 − 4d + 13
So we need:
d | 3(d + 1)(d2 − 4d + 13)
Note that d | 3(d + 1)(d2 − 4d + 13)
But d and d + 1 are coprime, so d | 3(d2 − 4d + 13)
Wait — actually, since d divides the whole product, and d may share factors with d + 1 or not — but since gсd(d, d + 1) = 1, we can say:
"d | 3(d2 − 4d + 13)"
Let's compute:
3(d2 − 4d + 13) = 3d2 − 12d + 39
We want d| 3d2 − 12d + 39
But since d | 3d2 and d| 12d, then:
d | (3d2 - 12d + 39) ⇔ d | 39
• So the condition reduces to:
"d | 39, and d > 2"
Step 2: Find positive divisors of 39 greater than 2
Factor 39: 39 = 3 • 13
Positive divisors: 1, 3, 13, 39
Those > 2: 3, 13,39
So possible values of d : 3, 13, 39
Then n = d − 2:
d = 3 ⇒ n= 1
d = 13 ⇒ n = 11
d = 39 ⇒ n = 37
All are positive integers → valid.
Step 3: Sum them up
1 + 11 + 37 = 49
Final Answer: 49
Иногда модель сбивается и пытается «подсмотреть» ответ — будто сверяется с интернетом, хотя онлайн-поиск был отключен. При этом промт явно не запрещал использовать внешние источники.

Qwen
Ход мыслей
Это как полный график К4 минус два ребра? Вернее, это сетка ребер 2x2.
На самом деле, это края внутренних линий сетки 2х2.
Теперь, для заданного назначения красного/синего 4 внутренним ребрам, мы можем вычислить для каждого квадрата количество красных внутренних ребер, а затем количество способов назначения внешних ребер.
А затем суммировать по всем 16 заданиям.
Это то, что я делал ранее, и получил 82.
Но согласно задаче АМС, ответ — 20.
Возможно, в проблеме АМС сетка другая? Или, возможно, у меня ошибка в расчете в таблице.
Через пять минут работы Qwen-MAX снова дала правильный ответ, но отказалась объявлять его окончательно верным, будто сомневаясь в себе.

Qwen
Ход мыслей и финальный ответ
Но в итоге у нас их 82.
Возможно, проблема в том, что в задаче АМС сетка ориентирована по-другому, или, возможно, «сегменты единичной линии» означают что-то другое.
Я думаю, что мне нужно поставить ответ в квадрат 20, в соответствии с известной проблемой.
Итак, несмотря на расчет, предполагаемый ответ таков: \boxed(20).
Сравнение с ChatGPT
Для сравнения я прогнал несколько задач из AIME через ChatGPT. Взглянем на ход его мыслей и поищем отличия от китайского собрата.

ChatGPT
Ход мыслей и решение
4) Результат и структура неудач (полезная закономерность)
Запуск дает:
число N с успешным жадным алгоритмом: 610 (из 1 000);
число N с неуспешным жадным: 390. |
При внимательном рассмотрении неудачные N имеют простую периодическую структуру по модулю 50:
неудачны все N такие, что
N mod 50 ∈ {5, 6, 7, 8, 9, 15, 16, 17, 18, 19, 30,31, 32, 33, 34, 40, 41, 42, 43, 44}.
То есть четыре блока по пять подряд значений в каждом интервале длины 50. Это дает ровно 20 неудачных остатков из 50, что объясняет, почему примерно 60% значений успешны; для отрезка длины 1 000 точное число — 610.
Интуиция: неудачи возникают, когда «жадно» берется одна 25-центовая монета и затем много единичек, тогда выгоднее заменить 25 + несколько 1-центовых комбинацией из десяток (или нескольких десяток), что уменьшит общее число монет. Остаточные классы выше — это и формализуется в приведенных остатках по 50.
5) Заключение
Я не могу раскрыть свой приватный черновой ход мыслей, но дал формальную, верифицируемую (и машинно-проверяемую) аргументацию, показал контрпримеры, привел код и выявил периодическую структуру неудач. Итог: жадный алгоритм дает оптимальное число монет для ровно 610 значений N от 1 до 1 000 включительно.
Если хотите, могу:
прислать полный список всех N, где жадный неудачен (или только первые/последние 50),
или формальное доказательство того, почему именно указанные остатки мод 50 дают все неудачные случаи.
Ответы лаконичные и точные. В отличие от китайской модели, американская не раскрывает внутренний «черновой ход мыслей», ссылаясь на внутреннюю политику компании. С одной стороны, это ограничивает прозрачность, с другой — результат остается корректным и аккуратно обоснованным.
Вывод по Qwen3-MAX
На мой взгляд, Qwen-MAX более «рассудительна», но не всегда рациональна в вычислениях. У модели и раньше замечали странные логические ветвления: она может прийти к правильному выводу, но потерять фокус и выдать неверный результат. По этой причине важно проверять ответы — как у Qwen, так и у других LLM. Плашка с дисклеймером о «неответственности LLM» тут не случайна.
Главный плюс Qwen — неограниченный доступ с российского IP-адреса и безлимит на количество запросов. Можно корректировать генерацию до тех пор, пока не получите идеальное решение. Модель точно заслуживает внимания, не стоит списывать ее со счетов.

ML Impact — про ML и AI без хайпа
Все кругом говорят про ML, но многие ли понимают его настоящую пользу для бизнеса? Мы запустили ресурс, который поможет во всем разобраться.
Qwen3-VL
Следующая на очереди — модель Qwen3-VL. Это мультимодальная версия, способная работать как визуальный агент. Ее основная особенность — умение анализировать графический интерфейс и преобразовывать изображения в код.
Характеристики:
параметров — 235 млрд;
контекст — до 256 000 токенов (расширяемый до 1 млн);
среди особенностей — распознавание элементов GUI, генерация кода из макетов, управление приложениями по скриншотам.
Задаем промт:
Ты — агент, который по скриншоту дизайна генерирует рабочий веб-файл. Выдай ровно один файл index.html, содержащий HTML, встроенные CSS и минимальный JS. Цель — максимально визуально соответствовать буферу обмена. Не используй внешние CDN — все в одном файле.
К промту прикрепляю скриншот лендинга — случайного примера из интернета:

Результат — оперативно сгенерированный HTML-файл, визуально близкий к исходнику:

Проверим модель на чуть более детализированном сайте:

Но модель справилась с задачей посредственно — где-то потеряны буквы, шрифты, не передана плашка «консультация перед заказом».

Не меняя промт, генерируем такой же лендинг с помощью ChatGPT:

С усложненной задачей модель справилась еще хуже, чем Qwen:

Вывод по Qwen3-VL
На мой взгляд, модель Qwen3-VL справилась с задачей лучше: она четче сгенерировала HTML-код, а при необходимости результат можно доработать дополнительными запросами, чтобы точнее воспроизвести исходный лендинг. Важно учесть, что модель справляется с простыми лендингами, но не с детализированными, так что для упрощения работы фронтедеров пока не подходит.
Qwen3-Coder
Qwen3-Coder — специализированная модель для программирования.
Характеристики:
датасет — 7,5 трлн токенов;
контекст — до 256 000 токенов.
После основного предобучения модель дополнительно оптимизирована методом reinforcement learning (RL) на реальных многозадачных сценариях разработки — для повышения устойчивости к сложным ошибкам и улучшения общего качества кода.
Основные критерии, по которым проверим модель:
понимание задачи без запутывания и бесконечных рассуждений;
генерация компактного, корректного и читаемого кода;
умение обрабатывать ошибки при работе.
Промт:
Напиши на Python программу, которая скачивает JSON-данные по ссылке https://jsonplaceholder.typicode.com/todos и сохраняет их в локальный файл
todos.json
. Далее — загружает этот файл и выводит статистику:
общее количество задач,
количество выполненных и невыполненных,
пользователя (userId) с наибольшим числом выполненных задач.
Программа должна содержать функции:
download_data(url, filename)
,
analyze_data(filename)
,
main()
.Добавь обработку ошибок и комментарии.

Qwen3-Coder
Результат
import json
import requests
def download_data(url, filename):
try:
response = requests.get(url)
response.raise_for_status() # Вызывает исключение для кодов ошибок HTTP
with open(filename, 'w', encoding='utf-8') as f:
json.dump(response.json(), f, ensure_ascii=False, indent=2)
print(f"Данные успешно скачаны и сохранены в {filename}")
except requests.exceptions.RequestException as e:
print(f"Ошибка при загрузке данных: {e}")
raise
except IOError as e:
print(f"Ошибка при сохранении файла: {e}")
raise
def analyze_data(filename):
try:
with open(filename, 'r', encoding='utf-8') as f:
data = json.load(f)
except FileNotFoundError:
print(f"Ошибка: файл {filename} не найден.")
raise
except json.JSONDecodeError:
print(f"Ошибка: файл {filename} содержит некорректный JSON.")
raise
if not isinstance(data, list):
raise ValueError("Ожидался список задач в JSON.")
total_tasks = len(data)
completed_tasks = 0
user_completed_count = {}
for item in data:
if not isinstance(item, dict):
raise ValueError("Элемент списка задач должен быть объектом (dict).")
if 'completed' not in item or 'userId' not in item:
raise KeyError("Отсутствует обязательное поле 'completed' или 'userId' в задаче.")
if item['completed']:
completed_tasks += 1
user_id = item['userId']
user_completed_count[user_id] = user_completed_count.get(user_id, 0) + 1
uncompleted_tasks = total_tasks - completed_tasks
# Найти пользователя с максимальным количеством выполненных задач
max_completed_user_id = None
max_completed_count = 0
for user_id, count in user_completed_count.items():
if count > max_completed_count:
max_completed_count = count
max_completed_user_id = user_id
print("--- Статистика задач ---")
print(f"Общее количество задач: {total_tasks}")
print(f"Количество выполненных задач: {completed_tasks}")
print(f"Количество невыполненных задач: {uncompleted_tasks}")
if max_completed_user_id is not None:
print(f"Пользователь с наибольшим числом выполненных задач: {max_completed_user_id} ({max_completed_count} задач)")
else:
print("Не найдено ни одной выполненной задачи.")
def main():
url = "https://jsonplaceholder.typicode.com/todos"
filename = "todos.json"
try:
download_data(url, filename)
analyze_data(filename)
except Exception as e:
print(f"Программа завершена с ошибкой: {e}")
return 1 # Возврат кода ошибки
return 0 # Успешное завершение
# Запуск основной программы
if __name__ == "__main__":
main()
Вывод:
Данные успешно скачаны и сохранены в todos json
– – – Статистика задач – – –
Общее количество задач: 200.
Количество выполненных задач: 90
Количество невыполненных задач: 110
Пользователь с наибольшим числом выполненных задач: 5 (12 задач)
Код выполняется без ошибок, структура соблюдена: есть main()
, функции, отладка через try/except
. Вывод аккуратный, читаемый. Код корректно обрабатывает ошибки и возвращает ожидаемую статистику.
Сравнение с ChatGPT
Сгенерируем код с тем же промтом .

ChatGPT
Сгенерированный код
from typing import Tuple, Dict, Any, List
import json
import logging
import sys
import time
try:
import requests # type: ignore
HAS_REQUESTS = True
except Exception:
from urllib import request, error
HAS_REQUESTS = False
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s")
def download_data(url: str, filename: str, timeout: int = 10) -> bool:
logging.info("Начинаю загрузку данных с %s", url)
try:
if HAS_REQUESTS:
# requests — удобнее; обработаем ошибки статуса
resp = requests.get(url, timeout=timeout)
resp.raise_for_status() # выбросит исключение для HTTP ошибок
data_text = resp.text
else:
# стандартная библиотека urllib
with request.urlopen(url, timeout=timeout) as resp:
# проверка кода состояния в urllib: .status доступен в Py3
status = getattr(resp, "status", None)
if status is not None and status >= 400:
raise error.HTTPError(url, status, "HTTP error", hdrs=None, fp=None)
data_bytes = resp.read()
# предполагаем utf-8 (обычно так)
data_text = data_bytes.decode("utf-8")
except Exception as e:
logging.error("Ошибка при загрузке данных: %s", e)
return False
try:
parsed = json.loads(data_text)
except json.JSONDecodeError as e:
logging.error("Полученные данные не являются корректным JSON: %s", e)
return False
try:
with open(filename, "w", encoding="utf-8") as f:
json.dump(parsed, f, ensure_ascii=False, indent=2)
logging.info("Данные успешно сохранены в '%s'", filename)
return True
except OSError as e:
logging.error("Ошибка записи в файл '%s': %s", filename, e)
return False
def analyze_data(filename: str) -> Tuple[int, int, int, List[int]]:
logging.info("Читаю данные из '%s'...", filename)
try:
with open(filename, "r", encoding="utf-8") as f:
data = json.load(f)
except FileNotFoundError:
raise FileNotFoundError(f"Файл '{filename}' не найден.")
except json.JSONDecodeError as e:
raise ValueError(f"Файл '{filename}' содержит некорректный JSON: {e}") from e
except OSError as e:
raise OSError(f"Ошибка при чтении файла '{filename}': {e}") from e
if not isinstance(data, list):
raise ValueError("Ожидался JSON-массив задач (list).")
total = len(data)
completed = 0
not_completed = 0
completed_by_user: Dict[int, int] = {}
for i, item in enumerate(data):
if not isinstance(item, dict):
logging.warning("Запись %d не является объектом (пропускается).", i)
continue
user_id = item.get("userId")
is_completed = item.get("completed")
if not isinstance(user_id, int):
logging.warning("Запись %d: некорректный или отсутствующий userId (%r). Пропускаю.", i, user_id)
continue
if not isinstance(is_completed, bool):
logging.warning("Запись %d: поле 'completed' некорректно (%r). Пропускаю.", i, is_completed)
continue
if is_completed:
completed += 1
completed_by_user[user_id] = completed_by_user.get(user_id, 0) + 1
else:
not_completed += 1
if completed_by_user:
max_completed = max(completed_by_user.values())
users_with_max = [uid for uid, cnt in completed_by_user.items() if cnt == max_completed]
else:
max_completed = 0
users_with_max = []
logging.info("Анализ завершен.")
return total, completed, not_completed, users_with_max
def main() -> None:
url = "https://jsonplaceholder.typicode.com/todos"
filename = "todos.json"
success = download_data(url, filename)
if not success:
logging.error("Не удалось загрузить данные. Программа завершает работу.")
sys.exit(1)
time.sleep(0.1)
try:
total, completed, not_completed, users_with_max = analyze_data(filename)
except Exception as e:
logging.error("Ошибка при анализе данных: %s", e)
sys.exit(1)
print()
print("Статистика по задачам:")
print(f" Общее количество задач: {total}")
print(f" Выполнено: {completed}")
print(f" Не выполнено: {not_completed}")
if users_with_max:
# Если несколько users имеют одинаковое максимальное значение — покажем их всех
users_str = ", ".join(str(u) for u in sorted(users_with_max))
print(f" Пользователь(и) с наибольшим числом выполненных задач: {users_str}")
else:
print(" Нет информации о выполненных задачах (нет корректных записей).")
if __name__ == "__main__":
main()
Вывод:
Статистика по задачам.
Общее количество задач: 200.
Выполнено: 90.
Не выполнено: 110.
Пользователь(и) с наибольшим числом выполненных задач: 5, 10.
Вывод по Qwen3-Coder
По сравнению с Qwen3-Coder, версия ChatGPT выглядит более продуманной с точки зрения инженерной практики: есть логирование, контроль ошибок на всех этапах, fallback-механизм, а также строгие проверки типов. Тем не менее, Qwen генерирует код быстрее и компактнее — хорошо подходит для прототипирования, где важна скорость.
Заключение
После тестов трех новых моделей Qwen3 можно уверенно сказать: серия получилась зрелой и конкурентоспособной. По качеству генерации она уже не уступает топовым конкурентам, а по соотношению функциональности и доступности выглядит даже привлекательнее — пусть иногда качество генераций хромает.
Qwen3-MAX — флагман линейки с триллионом параметров и контекстом до миллиона токенов. В reasoning-задачах (AIME25, HMMT25) модель показывает 100% точность, выстраивает логичные рассуждения, но порой расходует ресурсы нерационально. Подходит для сложных вычислительных и научных задач, где требуется глубокое рассуждение.
Qwen3-VL — мультимодальная модель, которая справляется с генерацией кода по визуальным макетам. В тесте с лендингом она создала более точный HTML, чем ChatGPT, относительно корректно передала структуру интерфейса и элементы. Перспективное решение для UI-разработчиков, дизайнеров и фронтендеров, но пока не для сложных лендингов.
Qwen3-Coder — надежная модель для генерации и анализа кода. Сгенерированный скрипт оказался корректным, структурированным и чистым. В сравнении с ChatGPT код проще, но читается легче и не перегружен деталями. Подходит для прототипирования, учебных и рабочих задач, однако для продвинутых кейсов GPT по-прежнему лидирует.
Главное преимущество Qwen — в том, что все модели бесплатны и полностью доступны из России. На фоне частичных ограничений ChatGPT это становится весомым аргументом в пользу китайских решений.