The right way to Create an LLM-Powered app to Convert Textual content to Presentation Slides: GenSlide — A Step-by-step Information

Picture by Mitchell Luo on Unsplash

On this submit, I’m going to share how one can create a easy but highly effective utility that makes use of LLMs to transform your written content material into concise PowerPoint slides. The great half: You even run your personal LLM service, so

  • you retain your knowledge non-public, and
  • no price to name LLM APIs.

Reaching the facility of GenSlide is simple. Observe these steps to arrange and run this device in your machine.

Start by creating the challenge folder in your native machine:

mkdir GenSlide

After finishing all of the steps, the ultimate file construction would appear like this:

GenSlide
├── frontend
│ ├── llm_call.py
│ ├── slide_deck.py
│ ├── slide_gen.py
│ └── ui.py
├── llm-service
│ ├── consts.py
│ └── gpt.py
└── necessities.txt

The primary file we create comprises packages record. Create a file named necessities.txt. Add the next bundle dependencies to the file.

pillow==10.3.0
lxml==5.2.2
XlsxWriter==3.2.0
python-pptx==0.6.23
gpt4all==2.7.0
Flask==2.2.5
Flask-Cors==4.0.0
streamlit==1.34.0

Particularly, we’re leveraging the gpt4all bundle to run a big language mannequin (LLM) server on an area machine. To dive deeper into gpt4all, confer with their official documentation.

We additionally use streamlit bundle to create the consumer interface.

Subsequent, create a digital atmosphere and set up the mandatory packages:

python -m venv ./venv
supply ./venv/bin/activate
pip set up -r necessities.txt

Be aware: Guarantee that you’re utilizing a Python model aside from 3.9.7, as streamlit is incompatible with that model. For this tutorial I used Python model 3.12.

Our LLM service ought to be capable of obtain a textual content as enter and generate a abstract of the important thing factors of the textual content as output. It ought to manage the output in an inventory of JSON objects. We’ll specify these particulars within the immediate definition. Let’s first create a folder for LLM service.

mkdir llm-service

We prepare the implementation into two .py recordsdata on this folder.

  1. consts.py

Right here we have to outline the identify of LLM mannequin we wish to use. You’ll be able to see the record of fashions that can be utilized right here: https://docs.gpt4all.io/gpt4all_python/house.html#load-llm. Meta’s Llama mannequin performs good for this job.

LLM_MODEL_NAME = "Meta-Llama-3-8B-Instruct.Q4_0.gguf"

We additionally outline the immediate message right here that features the directions to the LLM in addition to some examples of the specified output. We ask the output to be in JSON format, so it might be simpler for us to course of and create a presentation.

PROMPT = """
Summarize the enter textual content and prepare it in an array of JSON objects to to be appropriate for a powerpoint presentation.
Decide the wanted variety of json objects (slides) based mostly on the size of the textual content.
Every key level in a slide ought to be restricted to as much as 10 phrases.
Contemplate most of 5 bullet factors per slide.
Return the response as an array of json objects.
The primary merchandise within the record should be a json object for the title slide.
It is a pattern of such json object:
{
"id": 1,
"title_text": "My Presentation Title",
"subtitle_text": "My presentation subtitle",
"is_title_slide": "sure"
}
And right here is the pattern of json knowledge for slides:
{"id": 2, title_text": "Slide 1 Title", "textual content": ["Bullet 1", "Bullet 2"]},
{"id": 3, title_text": "Slide 2 Title", "textual content": ["Bullet 1", "Bullet 2", "Bullet 3"]}

Please ensure that the json object is right and legitimate.
Do not output rationalization. I simply want the JSON array as your output.
"""

2. gpt.py

Right here we wish to create a Flask utility that receives HTTP POST requests from the purchasers and name the LLM mannequin to extract the abstract in a JSON illustration.

First issues first; import dependencies.

from flask import Flask, request
from flask_cors import CORS
import traceback
import logging
import os
from consts import LLM_MODEL_NAME, PROMPT

from gpt4all import GPT4All

Outline the host IP, port, Flask app and permit Cross-Origin Useful resource Sharing.

logger = logging.getLogger()

HOST = '0.0.0.0'
PORT = 8081

app = Flask(__name__)
CORS(app)

Outline a base folder to retailer the LLM mannequin. Right here with “MODEL_PATH” atmosphere variable we overwrite the default location of fashions set by gpt4all. Now the fashions will probably be saved within the challenge folder beneath “gpt_models/gpt4all/”. When GPT4All class is instantiated for the primary time, it should search for the model_name within the model_path (it’s argument), if not discovered, will look into MODEL_PATH. If not discovered, it should begin to obtain the mannequin.

strive:
base_folder = os.path.dirname(__file__)
base_folder = os.path.dirname(base_folder)
gpt_models_folder = os.path.be part of(base_folder, "gpt_models/gpt4all/")
if not os.path.exists(gpt_models_folder):
os.makedirs(gpt_models_folder, exist_ok=True)
model_folder = os.environ.get("MODEL_PATH", gpt_models_folder)
llm_model = GPT4All(model_name=LLM_MODEL_NAME, model_path=model_folder)
besides Exception:
increase ValueError("Error loading LLM mannequin.")

Outline a operate to name the generate() operate of the LLM mannequin and return the response. We could set non-obligatory parameters corresponding to temperature and max_tokens.

def generate_text(content material):
immediate = PROMPT + f"n{content material}"

with llm_model.chat_session():
output = llm_model.generate(immediate, temp=0.7, max_tokens=1024)
output = output.strip()

return output

Outline a POST API to obtain purchasers’ requests. Requests come within the type of JSON objects {“content material”:”…”}. We’ll use this “content material” worth and name the generate_text() methodology outlined above. If every thing goes effectively, we ship the output together with an 200 HTTP (OK) standing code. In any other case an “Error” message and standing code 500 is returned.

@app.route('/api/completion', strategies=['POST'])
def completion():
strive:
req = request.get_json()
phrases = req.get('content material')
if not phrases:
increase ValueError("No enter phrase.")
output = generate_text(phrases)
return output, 200
besides Exception:
logger.error(traceback.format_exc())
return "Error", 500

Run the Flask app.

if __name__ == '__main__':
# run internet server
app.run(host=HOST,
debug=True, # computerized reloading enabled
port=PORT)

Frontend is the place we get the consumer’s enter and work together with the LLM service and at last create the PowerPoint slides.

Contained in the challenge folder, create a folder named frontend.

mkdir frontend

The implementation falls into 4 Python recordsdata.

  1. llm_call.py

This could be the place we ship the POST requests to the LLM server. We set our LLM server on localhost port 8081. We enclose the enter textual content right into a JSON object with the important thing “content material”. The output of the decision ought to be a JSON string.

import requests

URL = "http://127.0.0.1:8081"

CHAT_API_ENDPOINT = f"{URL}/api/completion"

def chat_completion_request(content material):
headers = {'Content material-type': 'utility/json'}
knowledge = {'content material': content material}

req = requests.submit(url=CHAT_API_ENDPOINT, headers=headers, json=knowledge)
json_extracted = req.textual content
return json_extracted

2. slide_deck.py

Right here we use pptx bundle to create PowerPoint slides. The record of JSON objects comprises the knowledge so as to add slides to the presentation. For detailed details about pptx bundle confer with their documentation.

import os

from pptx import Presentation
from pptx.util import Inches

class SlideDeck:

def __init__(self, output_folder="generated"):
self.prs = Presentation()
self.output_folder = output_folder

def add_slide(self, slide_data):
prs = self.prs
bullet_slide_layout = prs.slide_layouts[1]
slide = prs.slides.add_slide(bullet_slide_layout)
shapes = slide.shapes

# Title
title_shape = shapes.title
title_shape.textual content = slide_data.get("title_text", "")

# Physique
if "textual content" in slide_data:
body_shape = shapes.placeholders[1]
tf = body_shape.text_frame
for bullet in slide_data.get("textual content", []):
p = tf.add_paragraph()
p.textual content = bullet
p.stage = 0

if "p1" in slide_data:
p = tf.add_paragraph()
p.textual content = slide_data.get("p1")
p.stage = 1

if "img_path" in slide_data:
cur_left = 6
for img_path in slide_data.get("img_path", []):
prime = Inches(2)
left = Inches(cur_left)
peak = Inches(4)
pic = slide.shapes.add_picture(img_path, left, prime, peak=peak)
cur_left += 1

def add_title_slide(self, title_page_data):
# title slide
prs = self.prs
title_slide_layout = prs.slide_layouts[0]
slide = prs.slides.add_slide(title_slide_layout)
title = slide.shapes.title
subtitle = slide.placeholders[1]
if "title_text" in title_page_data:
title.textual content = title_page_data.get("title_text")
if "subtitle_text" in title_page_data:
subtitle.textual content = title_page_data.get("subtitle_text")

def create_presentation(self, title_slide_info, slide_pages_data=[]):
strive:
file_name = title_slide_info.get("title_text").
decrease().substitute(",", "").substitute(" ", "-")
file_name += ".pptx"
file_name = os.path.be part of(self.output_folder, file_name)
self.add_title_slide(title_slide_info)
for slide_data in slide_pages_data:
self.add_slide(slide_data)

self.prs.save(file_name)
return file_name
besides Exception as e:
increase e

3. slide_gen.py

Let’s break it into smaller snippets.

Right here, after importing mandatory packages, create a folder to retailer the generated .pptx recordsdata.

import json
import os

from slide_deck import SlideDeck
from llm_call import chat_completion_request

FOLDER = "generated"

if not os.path.exists(FOLDER):
os.makedirs(FOLDER)

Then outline these two strategies:

  • A technique to invoke chat_completion_request and ship the request to the LLM and parse the JSON string,
  • A technique that will get the output of earlier methodology and instantiate a SlideDeck to fill within the PowerPoint slides.
def generate_json_list_of_slides(content material):
strive:
resp = chat_completion_request(content material)
obj = json.masses(resp)
return obj
besides Exception as e:
increase e

def generate_presentation(content material):
deck = SlideDeck()
slides_data = generate_json_list_of_slides(content material)
title_slide_data = slides_data[0]
slides_data = slides_data[1:]
return deck.create_presentation(title_slide_data, slides_data)

4. ui.py

We create a easy UI with an enter textual content field. Consumer can kind in or copy/paste their textual content there and hit enter to start out the slide era. Upon completion of slide era, a message is printed on the finish of enter textual content field. streamlit could be very useful right here.

import traceback
import streamlit as st

from slide_gen import generate_presentation

def create_ui():
st.write("""
# Gen Slides
### Producing powerpoint slides on your textual content
""")

content material = st.text_area(label="Enter your textual content:", peak=400)
strive:
if content material:
filename = generate_presentation(content material)
st.write(f"file {filename} is generated.")
besides Exception:
st.write("Error in producing slides.")
st.write(traceback.format_exc())

if __name__ == "__main__":
create_ui()

Navigate to the llm-service folder and run the gpt.py file:

cd llm-service
python gpt.py

Be aware: The primary time you run this, the LLM mannequin will probably be downloaded, which can take a number of minutes to finish.

Now, it’s time to convey up the UI. Navigate to the frontend folder and run the ui.py file utilizing Streamlit:

cd ..
cd frontend
streamlit run ui.py

This command will launch the UI in your default internet browser.

With the UI up and operating, comply with these easy steps to generate your presentation:

1. Enter Textual content: Within the offered textual content field, enter the content material you’d like to rework right into a presentation. Right here is the pattern you might use:

Synthetic Intelligence is an concept that has been fascinating society because the mid-Twentieth century.
It started with science fiction familiarizing the world with the idea however the concept wasn't absolutely seen within the scientific method till Alan Turing, a polymath, was curious concerning the feasibility of the idea.
Turing's groundbreaking 1950 paper, "Computing Equipment and Intelligence," posed basic questions on machine reasoning much like human intelligence, considerably contributing to the conceptual groundwork of AI.
The event of AI was not very fast at first due to the excessive prices and the truth that computer systems weren't capable of retailer instructions.
This modified throughout the 1956 Dartmouth Summer time Analysis Challenge on AI the place there was an inspiring name for AI analysis, setting the precedent for 20 years of fast developments within the discipline.

2. Generate Slides: When you enter the textual content (adopted by Command ⌘ + Enter keys in Mac), GenSlide will course of it and create the presentation .pptxfile.

3. Entry Your Slides: The newly created PowerPoint file will probably be saved within thefrontend/generatedfolder.

Consumer Interface to enter the textual content
Generated PowerPoint slides