<НА ГЛАВНУЮ

Создание ультра-легкого AI помощника для кодирования с Mistral Devstral для систем с ограниченным дисковым пространством

Руководство по созданию легкого AI помощника для кодирования на базе Mistral Devstral, оптимизированного для работы в условиях ограниченного диска и памяти. Включает установку, загрузку модели с квантизацией, демонстрации и интерактивный режим.

Эффективная установка и управление кэшем

В этом руководстве показано, как создать легкий AI помощник для кодирования с использованием модели Mistral Devstral, оптимизированной для сред с ограниченным дисковым пространством и памятью, например Google Colab. Начинается установка минимального набора необходимых пакетов: kagglehub, mistral-common, bitsandbytes, transformers, accelerate и torch без кеширования для снижения использования диска. Определена функция очистки кэша, которая удаляет ненужные файлы из директорий /root/.cache и /tmp/kagglehub, обеспечивая оптимальное свободное место до и после работы с моделью.

def cleanup_cache():
   """Очистка ненужных файлов для экономии дискового пространства"""
   cache_dirs = ['/root/.cache', '/tmp/kagglehub']
   for cache_dir in cache_dirs:
       if os.path.exists(cache_dir):
           shutil.rmtree(cache_dir, ignore_errors=True)
   gc.collect()
 
cleanup_cache()
print(" Оптимизация дискового пространства выполнена!")

Загрузка ультра-компрессированной модели Devstral

Основной компонент — класс LightweightDevstral, который загружает модель devstral-small-2505 в потоковом режиме через kagglehub, избегая повторных скачиваний. Модель загружается с агрессивной 4-битной квантизацией с помощью BitsAndBytesConfig, что минимизирует использование памяти и диска при сохранении производительности. Инициализируется кастомный токенизатор, специфичный для Mistral Devstral. После загрузки кэш очищается снова для поддержания минимального использования диска (~2 ГБ).

class LightweightDevstral:
   def __init__(self):
       print(" Загрузка модели (потоковый режим)...")
      
       self.model_path = kagglehub.model_download(
           'mistral-ai/devstral-small-2505/Transformers/devstral-small-2505/1',
           force_download=False 
       )
      
       quantization_config = BitsAndBytesConfig(
           bnb_4bit_compute_dtype=torch.float16,
           bnb_4bit_quant_type="nf4",
           bnb_4bit_use_double_quant=True,
           bnb_4bit_quant_storage=torch.uint8,
           load_in_4bit=True
       )
      
       print(" Загрузка ультра-компрессированной модели...")
       self.model = AutoModelForCausalLM.from_pretrained(
           self.model_path,
           torch_dtype=torch.float16,
           device_map="auto",
           quantization_config=quantization_config,
           low_cpu_mem_usage=True, 
           trust_remote_code=True
       )
      
       self.tokenizer = MistralTokenizer.from_file(f'{self.model_path}/tekken.json')
      
       cleanup_cache()
       print(" Легкий помощник готов! (~2 ГБ на диске)")
  
   def generate(self, prompt, max_tokens=400): 
       """Генерация с экономией памяти"""
       tokenized = self.tokenizer.encode_chat_completion(
           ChatCompletionRequest(messages=[UserMessage(content=prompt)])
       )
      
       input_ids = torch.tensor([tokenized.tokens])
       if torch.cuda.is_available():
           input_ids = input_ids.to(self.model.device)
      
       with torch.inference_mode(): 
           output = self.model.generate(
               input_ids=input_ids,
               max_new_tokens=max_tokens,
               temperature=0.6,
               top_p=0.85,
               do_sample=True,
               pad_token_id=self.tokenizer.eos_token_id,
               use_cache=True 
           )[0]
      
       del input_ids
       torch.cuda.empty_cache() if torch.cuda.is_available() else None
      
       return self.tokenizer.decode(output[len(tokenized.tokens):])
 
print(" Инициализация легкого AI помощника...")
assistant = LightweightDevstral()

Демонстрация возможностей кодирования

Набор демонстраций показывает способности помощника к кодированию: написание функции проверки простого числа, отладка Python-функции и создание класса для анализа текста. Каждая демонстрация отправляет запрос помощнику, выводит результат и очищает память для сохранения отзывчивости.

def run_demo(title, prompt, emoji=""):
   """Запуск одной демонстрации с очисткой"""
   print(f"\n{emoji} {title}")
   print("-" * 50)
  
   result = assistant.generate(prompt, max_tokens=350)
   print(result)
  
   gc.collect()
   if torch.cuda.is_available():
       torch.cuda.empty_cache()
 
 
run_demo(
   "Быстрый поиск простых чисел",
   "Напишите быструю функцию `is_prime(n)` с объяснениями и тестами.",
   ""
)
 
 
run_demo(
   "Отладьте этот код",
   """Исправьте ошибочную функцию и объясните проблемы:
```python
def avg_positive(numbers):
   total = sum([n for n in numbers if n > 0])
   return total / len([n for n in numbers if n > 0])
```""",
   ""
)
 
 
run_demo(
   "Создатель текстовых инструментов",
   "Создайте простой класс `TextAnalyzer` с методами подсчета слов, символов и проверки палиндрома.",
   ""
)

Интерактивный режим быстрого кодирования

Пользователи могут взаимодействовать с помощником через режим Quick Coding, ограниченный пятью запросами для экономии памяти. После каждого запроса выводится краткое решение, затем память активно очищается.

def quick_coding():
   """Легкая интерактивная сессия"""
   print("\n РЕЖИМ БЫСТРОГО КОДИРОВАНИЯ")
   print("=" * 40)
   print("Введите короткие запросы (введите 'exit' для выхода)")
  
   session_count = 0
   max_sessions = 5 
  
   while session_count < max_sessions:
       prompt = input(f"\n[{session_count+1}/{max_sessions}] Ваш запрос: ")
      
       if prompt.lower() in ['exit', 'quit', '']:
           break
          
       try:
           result = assistant.generate(prompt, max_tokens=300)
           print(" Решение:")
           print(result[:500]) 
          
           gc.collect()
           if torch.cuda.is_available():
               torch.cuda.empty_cache()
              
       except Exception as e:
           print(f" Ошибка: {str(e)[:100]}...")
      
       session_count += 1
  
   print(f"\n Сессия завершена! Память очищена.")

Мониторинг использования диска и советы по экономии места

В конце демонстрируется проверка использования диска с помощью команды df -h через subprocess и дается ряд советов по экономии места: ограничение генерации токенов, автоматическая очистка кэша, удаление помощника по завершении работы и перезапуск среды при проблемах с памятью.

def check_disk_usage():
   """Мониторинг использования диска"""
   import subprocess
   try:
       result = subprocess.run(['df', '-h', '/'], capture_output=True, text=True)
       lines = result.stdout.split('\n')
       if len(lines) > 1:
           usage_line = lines[1].split()
           used = usage_line[2]
           available = usage_line[3]
           print(f" Диск: использовано {used}, доступно {available}")
   except:
       print(" Проверка использования диска недоступна")
 
 
print("\n Руководство завершено!")
cleanup_cache()
check_disk_usage()
 
print("\n Советы по экономии места:")
print("• Модель занимает ~2 ГБ против оригинальных ~7 ГБ+")
print("• Автоматическая очистка кэша после каждого использования") 
print("• Ограничение генерации токенов для экономии памяти")
print("• Используйте 'del assistant' для освобождения ~2 ГБ после работы")
print("• Перезапускайте среду при проблемах с памятью")

Этот подход позволяет использовать возможности модели Mistral Devstral в условиях ограниченных ресурсов без потери скорости и удобства. Ассистент поддерживает генерацию кода в реальном времени, отладку и прототипирование с минимальным потреблением ресурсов.

🇬🇧

Switch Language

Read this article in English

Switch to English