<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Avani</title>
    <description>The latest articles on DEV Community by Avani (@avani_1ddeec48cfa80546e1e).</description>
    <link>https://dev.to/avani_1ddeec48cfa80546e1e</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4018008%2Ffce9ed8c-75f6-4427-95ae-59642c921196.jpg</url>
      <title>DEV Community: Avani</title>
      <link>https://dev.to/avani_1ddeec48cfa80546e1e</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/avani_1ddeec48cfa80546e1e"/>
    <language>en</language>
    <item>
      <title>Running Hugging Face Inference with Kiro: From Prompt to Working Summarizer</title>
      <dc:creator>Avani</dc:creator>
      <pubDate>Mon, 06 Jul 2026 15:11:11 +0000</pubDate>
      <link>https://dev.to/avani_1ddeec48cfa80546e1e/running-hugging-face-inference-with-kiro-from-prompt-to-working-summarizer-4g77</link>
      <guid>https://dev.to/avani_1ddeec48cfa80546e1e/running-hugging-face-inference-with-kiro-from-prompt-to-working-summarizer-4g77</guid>
      <description>&lt;p&gt;Pre-trained models are the backbone of modern NLP. Whether you're summarizing documents, classifying support tickets, or building semantic search, the Hugging Face &lt;code&gt;transformers&lt;/code&gt; library gives you access to thousands of models, but wiring up tokenization, device management, and batching correctly takes careful attention to detail.&lt;/p&gt;

&lt;p&gt;This post shows how Kiro handles that for you. We'll walk through a real example: building a &lt;strong&gt;text summarizer&lt;/strong&gt; using a pre-trained BART model, then iterating with Kiro to add GPU support and batching, all through natural conversation.&lt;/p&gt;

&lt;p&gt;Everything here was tested locally and verified. The output you see below is real — captured from actual script execution on a MacBook with no GPU.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Task: Summarize Documents with a Pre-Trained Model
&lt;/h2&gt;

&lt;p&gt;I wanted a script that takes paragraphs of text and produces concise summaries. The goal: use the Hugging Face &lt;code&gt;transformers&lt;/code&gt; library directly (not the &lt;code&gt;pipeline&lt;/code&gt; shortcut) so we have full control over tokenization, device placement, and generation parameters.&lt;/p&gt;

&lt;p&gt;Here's what I asked Kiro:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Write a Python script that loads a summarization model from Hugging Face and generates summaries for a list of input texts. Use the transformers library directly, not the pipeline abstraction. Pick the best model for the task."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What Kiro Generated: The Base Script
&lt;/h2&gt;

&lt;p&gt;Kiro selected &lt;code&gt;sshleifer/distilbart-cnn-12-6&lt;/code&gt; — a distilled version of BART trained on CNN/DailyMail. It has fewer parameters (~306M vs ~406M) with a halved decoder (6 layers instead of 12), so it downloads faster and runs faster on CPU while still producing quality summaries. It used &lt;code&gt;AutoModelForSeq2SeqLM&lt;/code&gt; (the correct class for encoder-decoder summarization models) without being told.&lt;/p&gt;

&lt;p&gt;Here's the core of what it produced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;transformers&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;AutoModelForSeq2SeqLM&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sshleifer/distilbart-cnn-12-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Load the tokenizer and model from Hugging Face Hub.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForSeq2SeqLM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;# Evaluation mode — disables dropout
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate summaries for a list of input texts.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Tokenize inputs with padding and truncation
&lt;/span&gt;    &lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;truncation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;return_tensors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Generate summaries without computing gradients
&lt;/span&gt;    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;no_grad&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="n"&gt;summary_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input_ids&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;attention_mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;attention_mask&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;min_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;num_beams&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;length_penalty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;early_stopping&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Decode generated token IDs back to text
&lt;/span&gt;    &lt;span class="n"&gt;summaries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;batch_decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summary_ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;skip_special_tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;summaries&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Key Steps Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Model Loading
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForSeq2SeqLM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kiro uses the &lt;code&gt;Auto&lt;/code&gt; classes — they detect the correct architecture from the model name. For summarization, that's &lt;code&gt;AutoModelForSeq2SeqLM&lt;/code&gt; (encoder-decoder). Under the hood, this loads a &lt;code&gt;BartForConditionalGeneration&lt;/code&gt; model and a &lt;code&gt;RobertaTokenizer&lt;/code&gt;. (BART shares its byte-level BPE vocabulary with RoBERTa — in fact &lt;code&gt;BartTokenizer&lt;/code&gt; is an alias for &lt;code&gt;RobertaTokenizer&lt;/code&gt; in the transformers library, so &lt;code&gt;AutoTokenizer&lt;/code&gt; resolves directly to &lt;code&gt;RobertaTokenizer&lt;/code&gt;.) &lt;code&gt;model.eval()&lt;/code&gt; switches off dropout for consistent inference output.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tokenization
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;truncation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;return_tensors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tokenizer converts raw strings into tensors. &lt;code&gt;padding=True&lt;/code&gt; ensures all sequences in a batch have equal length. &lt;code&gt;truncation=True&lt;/code&gt; clips inputs exceeding the 1024-token context window (verified: our long-text test confirmed truncation works gracefully). &lt;code&gt;return_tensors="pt"&lt;/code&gt; gives PyTorch tensors directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Inference (Generation)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;no_grad&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;summary_ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;input_ids&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;attention_mask&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;attention_mask&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;130&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;min_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;num_beams&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;length_penalty&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;early_stopping&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unlike classification (a single forward pass), summarization &lt;em&gt;generates&lt;/em&gt; new tokens autoregressively. &lt;code&gt;torch.no_grad()&lt;/code&gt; disables gradient computation for speed and memory savings. The generation parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;num_beams=4&lt;/code&gt; — beam search explores 4 candidate sequences in parallel&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;length_penalty=2.0&lt;/code&gt; — encourages longer, more complete summaries&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;early_stopping=True&lt;/code&gt; — stops when all beams produce an end token&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Iterating with Kiro: Adding GPU Support
&lt;/h2&gt;

&lt;p&gt;Next prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Update this to automatically use GPU if available, and fall back to CPU."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kiro added device detection and placement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_model&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sshleifer/distilbart-cnn-12-6&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Load model with automatic device selection.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;device&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;device&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cuda&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;torch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cuda&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_available&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cpu&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;tokenizer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoTokenizer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AutoModelForSeq2SeqLM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from_pretrained&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;truncation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;return_tensors&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Move inputs to same device as model
&lt;/span&gt;    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tested result&lt;/strong&gt;: On my MacBook (Apple M-series, no CUDA), the script correctly detects &lt;code&gt;CUDA available: False&lt;/code&gt; and falls back to CPU. Apple's MPS backend &lt;em&gt;is&lt;/em&gt; available (&lt;code&gt;torch.backends.mps.is_available() = True&lt;/code&gt;), but Kiro correctly uses the standard CUDA/CPU pattern that works universally.&lt;/p&gt;




&lt;h2&gt;
  
  
  Iterating with Kiro: Adding Batching
&lt;/h2&gt;

&lt;p&gt;Third prompt:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Add batching support so I can process large datasets without running out of memory. Use a configurable batch size."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Kiro added:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;summarize_batched&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Generate summaries in batches to handle large datasets.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;all_summaries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;batch_texts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;texts&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;batch_size&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;batch_summaries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;summarize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;batch_texts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tokenizer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;device&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;kwargs&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;all_summaries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;batch_summaries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;all_summaries&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Tested result&lt;/strong&gt;: I ran the same 4 texts with &lt;code&gt;batch_size=1&lt;/code&gt;, &lt;code&gt;batch_size=2&lt;/code&gt;, and &lt;code&gt;batch_size=4&lt;/code&gt;. All three produced identical summaries and correct result counts. The batching logic correctly slices, processes, and reassembles without losing or reordering results.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Output: The Final Script in Action
&lt;/h2&gt;

&lt;p&gt;Here's the actual terminal output from running the tested script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;python summarize.py
Loading model...
Model loaded on: cpu
Generating summaries...

&lt;span class="nt"&gt;---&lt;/span&gt; Text 1 &lt;span class="nt"&gt;---&lt;/span&gt;
Input:   The Amazon rainforest, often referred to as the lungs of the Earth, produces approximately 20 percen...
Summary: The Amazon rainforest produces approximately 20 percent of the world&lt;span class="s1"&gt;'s oxygen.
Spanning across nine countries in South America, it is home to an estimated 400 billion
individual trees representing over 16,000 species. Scientists continue to discover new
species every year.

--- Text 2 ---
Input:   Kubernetes has become the de facto standard for container orchestration in cloud-native applications...
Summary: Kubernetes is de facto standard for container orchestration in cloud-native
applications. It automates deployment, scaling, and management of containerized workloads
across clusters of machines. Key features include self-healing capabilities, horizontal
scaling, service discovery, and load balancing.

--- Text 3 ---
Input:   The new wireless earbuds feature active noise cancellation with three adjustable levels, 24-hour bat...
Summary: Wireless earbuds feature active noise cancellation, 24-hour battery life and IPX5
water resistance. Support Bluetooth 5.3 for stable connectivity and include touch controls
for playback and calls. Available in four colors.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Performance: What to Expect
&lt;/h2&gt;

&lt;p&gt;Measured on an Apple M-series MacBook (CPU inference):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model load (from cache):&lt;/strong&gt; 3.6s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inference (3 texts, single batch):&lt;/strong&gt; 6.5s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Per-text average:&lt;/strong&gt; 2.2s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Total end-to-end:&lt;/strong&gt; ~10s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batched (3 texts, batch_size=2):&lt;/strong&gt; 8.1s&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Peak memory:&lt;/strong&gt; ~2.5GB&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;First run downloads the 1.2GB model (~2 minutes on broadband). Subsequent runs load from &lt;code&gt;~/.cache/huggingface/&lt;/code&gt; in seconds. On a CUDA GPU, expect 5-10x inference speedup.&lt;/p&gt;

&lt;p&gt;Batched inference with &lt;code&gt;batch_size=2&lt;/code&gt; is slightly slower than processing all 3 at once (8.1s vs 6.5s) because of the overhead of two separate forward passes. The benefit shows with larger datasets where processing everything at once would exhaust memory.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Kiro Handles Well Here
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Model selection&lt;/strong&gt; — Chose &lt;code&gt;distilbart-cnn-12-6&lt;/code&gt; over the larger &lt;code&gt;bart-large-cnn&lt;/code&gt;. Recognized that a demo benefits from faster downloads and inference. Used the correct &lt;code&gt;AutoModelForSeq2SeqLM&lt;/code&gt; class without being told the architecture type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Correct API patterns&lt;/strong&gt; — &lt;code&gt;model.eval()&lt;/code&gt;, &lt;code&gt;torch.no_grad()&lt;/code&gt;, proper &lt;code&gt;attention_mask&lt;/code&gt; passing, beam search parameters, device placement. These patterns are scattered across Hugging Face docs — Kiro assembles them correctly in one pass.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterative refinement&lt;/strong&gt; — Each follow-up produced targeted changes. GPU support threaded a &lt;code&gt;device&lt;/code&gt; parameter through existing functions. Batching added a wrapper reusing the existing &lt;code&gt;summarize()&lt;/code&gt; function. No rewrites, no broken logic between iterations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Production structure&lt;/strong&gt; — Type hints, docstrings, configurable parameters, clean function separation. The code reads like something a senior engineer would write for a shared codebase.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  What I Verified Through Testing
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Basic execution (3 sample texts):&lt;/strong&gt; PASS — coherent summaries&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch consistency (bs=1 vs bs=2 vs bs=4):&lt;/strong&gt; PASS — identical results&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU detection and fallback:&lt;/strong&gt; PASS — graceful CPU fallback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Long text truncation (&amp;gt;1024 tokens):&lt;/strong&gt; PASS — truncated without error&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Short text handling:&lt;/strong&gt; PASS — produces output (though quality degrades)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API signatures and return types:&lt;/strong&gt; PASS — proper typing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance on CPU:&lt;/strong&gt; 2.2s/text — acceptable for non-realtime use&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tips for Working with Kiro on Hugging Face Models
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Name the task explicitly.&lt;/strong&gt; "Summarization" tells Kiro to use &lt;code&gt;AutoModelForSeq2SeqLM&lt;/code&gt; and &lt;code&gt;model.generate()&lt;/code&gt;. "Classification" triggers &lt;code&gt;AutoModelForSequenceClassification&lt;/code&gt; with softmax. The task name drives the architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask for the raw API when you need control.&lt;/strong&gt; The &lt;code&gt;pipeline("summarization")&lt;/code&gt; abstraction hides device management, generation parameters, and batching. The direct API gives you code you can tune.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Let Kiro pick the model.&lt;/strong&gt; It chose a distilled variant that's smaller and faster without sacrificing quality. You can override if you have a specific model in mind.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Iterate on non-functional requirements separately.&lt;/strong&gt; Get inference working first, then add GPU, batching, or error handling. Keeps each change focused.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Run It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;transformers torch
python summarize.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete script handles: model loading with automatic device selection, tokenization with padding and truncation, batched inference with configurable chunk size, beam search generation with quality parameters, and clean output formatting.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>nlp</category>
      <category>python</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
