Представьте: вы сидите в гараже, паяете очередной девайс, а рядом на ноутбуке крутится локальная LLM. У неё температура застыла на 0.7, top_p на 0.9 — скука смертная. Хочется, чтобы модель чувствовала атмосферу. Буквально. Вдруг запахло газом — и ИИ бахает креативом до потолка. Проверили вентиляцию — модель снова спокойна, как удав.
Это не фантастика. Это мы сегодня спаяем. Берём газовый сенсор MQ-2 (или MQ-135, если у вас аллергия на дешёвые модули), китайский Arduino Nano, пару проводов и чуть-чуть магии на стороне Python. Результат: LLM, чьи параметры семплинга зависят от концентрации газа в воздухе. Кринж? Возможно. Полезно? Для тестирования креативности — да. Для хайпа — ещё как.
Зачем газ совать в нейросеть?
Логика простая: высокая температура делает модель более «творческой» (читай — нестабильной и склонной к галлюцинациям), низкая top_p отсекает маловероятные токены, превращая генерацию в калькулятор. Газовый сенсор даёт аналоговый сигнал, который мы маппим в нужные нам диапазоны. Например:
- Концентрация газа 0–200 ppm → температура 0.2–0.5, top_p 0.7–0.6 (режим «безопасность, не галлюцинируй»).
- Концентрация 200–400 ppm → температура 0.5–1.2, top_p 0.6–0.9 (режим «утечка — креативь на всю катушку»).
- Выше 400 ppm → температура 1.5, top_p 0.95 (паника, полный хаос).
Конечно, можно было бы просто дёргать ползунки рандомом. Но с реальным датчиком появляется физический контекст: запахло — модель взбесилась. Это можно использовать в умных домах, в робототехнике, на стендах для демонстрации галлюцинаций.
Предупреждение! Газовый сенсор MQ-2 реагирует на метан, пропан, водород. Не используйте проект как реальную систему безопасности — это игрушка для экспериментов. Для детектора утечек берите промышленные датчики и пускайте сигнал напрямую на клапан отсечки, а не в LLM.
Шаг 1. Железо: MQ-2 + Arduino
Нам нужно, чтобы Arduino читал показания и отправлял их на ПК по USB (Serial). Я собирал на Nano, но подойдёт любой клон — хоть ESP32, если хотите добавить Wi-Fi. Схема:
- MQ-2 VCC → 5V (на некоторых модулях 3.3V, смотрите даташит).
- MQ-2 GND → GND.
- MQ-2 AOUT → A0 (аналоговый вход).
- Если модуль с DOUT (цифровой выход) — можно не подключать, нам нужен аналоговый.
Код для Arduino минимален:
void setup() {
Serial.begin(115200);
}
void loop() {
int sensorValue = analogRead(A0);
// Преобразуем в ppm (приблизительно, лучше калибровать)
float ppm = sensorValue * (5.0 / 1023.0) * 100; // грубая оценка
Serial.println(ppm);
delay(500);
}
Залейте скетч, откройте монитор порта — вы должны видеть числа, которые меняются, если поднести зажигалку (газ без пламени!) или баллончик с пропаном.
Шаг 2. Программный мост: Python читает Serial
На стороне ПК мы запускаем Python-скрипт, который:
- Читает строки из Serial.
- Парсит значение ppm.
- Вычисляет температуру и top_p по нужной функции.
- Передаёт их в LLM-семплер.
Я использовал библиотеку pyserial и transformers от Hugging Face (актуальная версия на июнь 2026 — 4.45.2). Можно также работать с llama.cpp через Python-биндинги, но transformers удобнее для прототипирования.
import serial
import time
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# Открываем порт (проверьте свой /dev/ttyUSB0 или COM3)
ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=1)
# Загружаем модель (например, Qwen2.5-7B или любую локальную)
model_name = "Qwen/Qwen2.5-7B-Instruct"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)
model.to('cuda')
def map_ppm_to_temperature(ppm):
# Простая линейная интерполяция
if ppm < 200:
return 0.3 + (ppm / 200) * 0.2 # 0.3–0.5
elif ppm < 400:
return 0.5 + ((ppm - 200) / 200) * 0.7 # 0.5–1.2
else:
return min(1.5, 1.2 + ((ppm - 400) / 200) * 0.3) # до 1.5
def map_ppm_to_topp(ppm):
if ppm < 200:
return 0.7 - (ppm / 200) * 0.1 # 0.7–0.6
elif ppm < 400:
return 0.6 - ((ppm - 200) / 200) * 0.3 # 0.6–0.3
else:
return max(0.1, 0.3 - ((ppm - 400) / 200) * 0.2)
print("Ждём данные с Arduino...")
while True:
line = ser.readline().decode().strip()
if line:
try:
ppm = float(line)
temp = map_ppm_to_temperature(ppm)
topp = map_ppm_to_topp(ppm)
print(f"PPM: {ppm:.0f} -> temp: {temp:.2f}, top_p: {topp:.2f}")
# Далее используем эти параметры при генерации
# Пример: генерируем ответ на заданный промпт
prompt = "Расскажи анекдот про газ."
inputs = tokenizer(prompt, return_tensors="pt").to('cuda')
outputs = model.generate(
**inputs,
max_new_tokens=100,
temperature=temp,
top_p=topp,
do_sample=True
)
answer = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"Модель: {answer}")
except ValueError:
pass
time.sleep(0.1)
Как НЕ надо делать: многие новички забывают, что do_sample=True обязателен, иначе temperature не сработает. Ещё частая ошибка — не переводить модель в режим eval. И не генерируйте без max_new_tokens, а то уйдёте в бесконечность.
Альтернативы: а как ещё «оживить» семплер?
Газовый сенсор — не единственный способ динамически менять параметры. Энтузиасты пробовали:
- Датчик температуры BME280 — чем холоднее, тем креативнее (логика «мёрзнешь — включай фантазию»).
- Микрофон + амплитуда звука — громкий шум = высокая температура (имитация стресса).
- Потенциометр на аналоговом входе — ручное управление без программирования.
- Случайные числа — дешёво и сердито, но без хардверного вайба.
Газовый датчик выигрывает за счёт «опасности» — когда в комнате реально воняет, LLM начинает нести чушь. Это отличный демо-стенд для лекций про чувствительность моделей к гиперпараметрам.
Примеры в реальном коде: «обонятельный ассистент»
Допустим, у вас есть робот с LLM, который должен реагировать на утечку газа. Если сенсор показывает >300 ppm, модель должна срочно придумать план эвакуации. Но если температура будет низкой, она станет «занудой» и начнёт рассуждать: «Согласно СНиПу, вентиляция должна быть открыта...» — а времени нет. Лучше поднять temperature — пусть выдаёт короткие, нестандартные решения.
Я тестировал это на Qwen2.5-7B. Без газа модель отвечала сухо (temp=0.4, top_p=0.7): «Откройте окно». С имитацией газа (temp=1.3, top_p=0.9): «Срочно! Звони 112, отключай электричество, беги на улицу!». Разница колоссальная.
Если хотите идти дальше, обязательно посмотрите как подключить Meshtastic к локальной LLM на ноутбуке — там похожая связка радиоканала и модели. Для тех, кто хочет развернуть всё на домашнем сервере, пригодится гайд Homelab для LLM: окупаем H100. А если думаете, куда воткнуть этот проект в умный дом — загляните в создание автономного AI-агента на LoRa.
Кому это вообще пригодится?
- Хардкорным DIY-щикам, у кого на столе валяется паяльник и Arduino.
- Исследователям семплинга, которые хотят наглядно показать, как temperature и top_p влияют на качество генерации (сами студенты подносят зажигалку и видят эффект).
- Робототехникам, строящим мобильного ассистента с «обонянием».
- Любителям странных стартапов, типа «нейросеть, которая нюхает газ и пишет стихи».
Инструмент не требует мощного GPU — даже на Radeon 6600 (через ROCm) или старом NVIDIA GTX 1060 можно крутить 7B модели. Если карты нет, используйте llama.cpp на CPU — потеряете в скорости, но концепцию отработаете. Подробности про настройку охлаждения DGX для таких экспериментов читайте в статье DGX Spark плавится? Собираем систему охлаждения.
Соберите, перепрограммируйте, удивитесь, как меняется характер модели. И помните: если LLM при газе начинает писать диссертацию по квантовой физике — значит, вы переборщили с температурой. Делайте по шагам.