Обновить

Можно ли быстро актуализировать старые PHPUnit-тесты под новые версии пакета?

Краткий ответ: да, но есть нюансы.

На Хабре незаслуженно мало статей про инструмент Rector, и даже в них совсем вскользь упоминается, что у инструмента есть отдельный функционал для актуализации PHPUnit-тестов, написанных под разные версии пакета. Причем если раньше, этот функционал был в виде отдельного пакета rector-phpunit, то на сегодня (для версии 2.6.3) этот функционал уже входит в состав основного пакета.

Итак, у нас были тесты написанные в разное время разными разработчиками под версию PHPUnit, которая была установлена при создании проекта. Вопрос о её обновлении поднимался регулярно, но оценка стоимости актуализации нескольких сотен файлов с несколькими тысячами тестов была довольно большой, пока не появилась возможность сделать это автоматически.

Как шло обновление:
- установили пакет rector/rector
- обновили пакет phpunit
- сделали файл конфига rector.php в котором прописали наборы правил
- запустили сначала в режиме vendor/bin/rector process --dry-run. Увидели, что аннотации @dataProvider не мигрировали в атрибуты #[DataProvider], а сами методы, на которые указывают dataProvider не стали статическими (требования PHPUint 10+).
Добавили необходимые правила в конфиг rector.php и в при первом приближении всё сработало как нужно:

<?php

declare(strict_types=1);

use Rector\Config\RectorConfig;

return RectorConfig::configure()
    // Путь к директории с тестами
    ->withPaths([
        __DIR__ . '/tests',
    ])
    // Включаем синтаксис PHP 8.4
    ->withPhpSets(php84: true)
    // Правила берем для версии phpunit из composer.json
    ->withComposerBased(
        phpunit: true
    )
    // Общие наборы правил для улучшения качества тестов
    ->withPreparedSets(
        phpunitCodeQuality: true
    )
    // Явно запускаем встроенное правило миграции аннотаций PHPUnit в атрибуты
    ->withAttributesSets(
        phpunit: true
    );

Но и после этих инструкций не все методы dataProvider стали статическими. Основные причины были в следующем:
- использование $this в методах dataProvider
- коллизии из-за последовательности выполнения правил рефакторинга в Rector

Что помогло исправить ситуацию:
1. повторный запуск vendor/bin/rector process позволил правилам повторно пройтись по уже исправленным файлам и доделать изменения
2. использование ссылки на текущий объект в методах dataProvider плохая практика, от неё отказались

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Как мы запустили Qwen3.8–27B целиком на RTX 5060 8 GB и получили ~30 токенов/с

Наш проект называется ExVRAM Lab. Это открытая исследовательская лаборатория, в которой мы проверяем, насколько большие локальные LLM можно запускать на обычных видеокартах с ограниченным объёмом VRAM, если использовать ultra‑low‑bit quantization, полное размещение весов на GPU и существующие open‑source inference‑технологии.

ExVRAM расшифровывается как Exchange Compute for VRAM. Основная идея проекта — в ряде сценариев выгоднее потратить часть свободной вычислительной мощности GPU на работу с более компактным представлением весов, чем хранить часть модели в оперативной памяти и постоянно передавать данные через PCIe.

Когда мы начинали проект, исходный вопрос был достаточно простой: можно ли запустить dense‑модель примерно на 27 миллиардов параметров на видеокарте всего с 8 ГБ VRAM так, чтобы она не просто «запустилась», а работала полностью на GPU, поддерживала длинный контекст и обеспечивала нормальную интерактивную скорость генерации.

В качестве основной тестовой системы мы используем NVIDIA GeForce RTX 5060 8 GB на архитектуре Blackwell. Основная модель в текущих экспериментах — Qwen3.8–27B.

Сначала результат выглядел не слишком впечатляюще. Модель запускалась, но значительная часть весов оставалась в системной памяти. Около 5,7 GiB весов находилось на GPU, ещё примерно 2,5 GiB — на CPU. Скорость генерации составляла порядка 3,8–5,5 токена в секунду.

При этом сама видеокарта была загружена далеко не полностью.

Это стало одним из первых важных наблюдений проекта. Проблема заключалась не столько в нехватке вычислительной мощности RTX 5060, сколько в том, что часть decoder weights находилась в RAM. Во время autoregressive generation данные приходилось постоянно передавать между CPU и GPU через PCIe.

Как мы запустили Qwen3.8–27B целиком на RTX 5060 8 GB и получили ~30 токенов/с

Публикации