--- license: apache-2.0 base_model: Qwen/Qwen3-8B tags: - rlvr - grpo - unsloth - code - qwen3 - trl datasets: - open-r1/verifiable-coding-problems-python library_name: peft --- # Qwen3 8B + SFT + GRPO (RLVR, coding) Qwen3-8B, дообученный в два этапа: SFT на 15k синтетических код-трейсов (багфикс / доработка / кодогенерация, thinking + tool-calling), затем **GRPO с верифицируемой наградой (RLVR)** для усиления кодинга: наградой служит прохождение скрытых stdin→stdout тестов, проверяемых в изолированной песочнице. ## Архитектура обучения | Этап | Что происходило | |---|---| | 1. SFT | 15k трейсов (bugfix/modify/codegen/vague), chat template Qwen3, think-цепочки ~450 токенов | | 2. RLVR | GRPO на 997 задачах с gold-верифицированными IO-тестами; LoRA r=16, lr 5e-6, beta=0.0 | ### Этап RLVR (детали) - **Задачи**: `open-r1/verifiable-coding-problems-python`, отфильтрованы строгим gold-фильтром: каноническое решение обязано пройти 100% скрытых тестов (выживаемость ~50%: отсев python2-решений, битых тестов, задач без скрытых кейсов). - **Награда**: трёхуровневое сравнение вывода (точное → по токенам → числовое с tolerance 1e-6), частичный pass rate по скрытым кейсам, бонус за полное решение и небольшой format reward. Публичные примеры из условия исключены из награды (защита от hardcoding-хаков). - **Формат**: `/no_think` — RL проводился на коротких ответах без длинных think-цепочек (длина генераций 70–600 токенов). - **Ход**: пилот 30 шагов на RTX L4 (reward MA5 +0.09 → +0.52), затем полный ран по датасету на RTX PRO 6000 (Blackwell). ## Результаты пилота За 30 шагов GRPO скользящее среднее награды выросло с +0.09 до +0.52 при живом reward_std (без коллапса в детерминированный ответ) и стабильной длине генераций в пределах лимита. ## Использование Модель обучена отвечать коротко, без длинного reasoning, код — одним python-блоком. Рекомендуемый формат запроса: системный промпт с требованием одного кодового блока, суффикс `/no_think` в сообщении пользователя. ```python from transformers import AutoModelForCausalLM, AutoTokenizer model = AutoModelForCausalLM.from_pretrained("voperl/Qwen3-8B-Code", torch_dtype="auto", device_map="auto") tok = AutoTokenizer.from_pretrained("voperl/Qwen3-8B-Code") messages = [ {"role": "system", "content": "Ты — опытный Python-разработчик. Дай готовый код одним python-блоком."}, {"role": "user", "content": "<задача>\n\n/no_think"}, ] inputs = tok.apply_chat_template(messages, return_tensors="pt", add_generation_prompt=True).to(model.device) out = model.generate(inputs, max_new_tokens=2048, temperature=0.0, do_sample=False) print(tok.decode(out[0][inputs.shape[1]:], skip_special_tokens=True)) ``` ## Ограничения - RLVR-этап обучал stdin/stdout-задачи; на прочих доменах (tool-calling, многословные код-ревью из SFT) поведение может сместиться — RL проводился в no-think формате. - Награда построена на тестах, а не на корректности рассуждений: модель может находить верные решения, рассуждая неточно. - Задачи с float-выводом: сравнение с допуском 1e-6, не строковое. ## Воспроизведение Стек: Unsloth + TRL GRPOTrainer, vLLM для rollout'ов, LoRA r=16 (все 7 проекций), lr 5e-6, beta 0.0, temperature 0.7, num_generations 4–8, max_completion 2048. Харнесс: subprocess-песочница с таймаутом 10 с/кейс, до 10 скрытых кейсов на задачу. This qwen3 model was trained 2x faster with [Unsloth](https://github.com/unslothai/unsloth) [](https://github.com/unslothai/unsloth)