Showing posts with label Azure Speech. Show all posts
Showing posts with label Azure Speech. Show all posts

18 June, 2024

πŸš€ Revolutionizing Document Interaction: An AI-Powered PDF Voice-2-Voice Chatbot Using LlamaIndex πŸ‘, Langchain πŸ”— Azure AI Speech 🎀and Google Audio πŸ”Š

Welcome to the third and last installment of this series on innovative AI-driven chatbots. In our journey from basic text-based interactions to text-2-voice-enabled capabilities, we now introduce a voice-2-voice-enabled PDF chatbot. This advanced system allows users to interact verbally with their PDF documents, significantly enhancing accessibility and usability. Let’s explore how this chatbot works and its implications for users.

Evolution of Chatbots: From Text to Voice

In our initial blog post, we introduced a text-based chatbot capable of processing queries from uploaded documents. This laid the groundwork for seamless interaction with textual information.

http://techiemate.blogspot.com/2024/06/revolutionizing-document-interaction-ai.html

Building on this, our second post showcased text to voice recognition integration, an interactive voice assistant capable of understanding and reading out the answer from the content in your PDFs. This enhancement marked a significant leap towards intuitive user engagement, catering to diverse user preferences and accessibility needs.

http://techiemate.blogspot.com/2024/06/revolutionizing-document-interaction-ai_13.html 

Introducing Voice-to-Voice Interaction with PDFs

Today, we introduce our latest innovation: a voice-enabled PDF chatbot capable of both transcribing spoken queries and delivering spoken responses directly from PDF documents. This breakthrough technology bridges traditional document interaction with modern voice-driven interfaces, offering a transformative user experience.

The Technical Backbone: Exploring the Codebase

Let’s delve into the technical components that power our voice-enabled PDF chatbot:

Setting Up Dependencies and Environment

import os
import faiss
import streamlit as st
from dotenv import load_dotenv
from langchain_core.messages import AIMessage, HumanMessage
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage
from llama_index.vector_stores.faiss import FaissVectorStore
import azure.cognitiveservices.speech as speechsdk
import speech_recognition as sr

# Initialize Faiss index for vectorization
d = 1536
faiss_index = faiss.IndexFlatL2(d)
PERSIST_DIR = "./storage"

# Load environment variables
load_dotenv()

The code snippet above sets up necessary dependencies:

  • Faiss: Utilized for efficient document vectorization, enabling similarity search based on content.
  • Streamlit: Facilitates the user interface for seamless interaction with the chatbot and document upload functionality.
  • LangChain: Powers the message handling and communication within the chatbot interface.
  • LlamaIndex: Manages the storage and retrieval of vectorized document data, optimizing query performance.
  • Azure Cognitive Services (Speech SDK): Provides capabilities for speech recognition and synthesis, enabling the chatbot to transcribe and respond to spoken queries.
  • Google Audio : Provides speech into text using Google’s speech recognition API.

Document Handling and Vectorization

def saveUploadedFiles(pdf_docs):
UPLOAD_DIR = 'uploaded_files'
try:
for pdf in pdf_docs:
file_path = os.path.join(UPLOAD_DIR, pdf.name)
with open(file_path, "wb") as f:
f.write(pdf.getbuffer())
return "Done"
except:
return "Error"

def doVectorization():
try:
vector_store = FaissVectorStore(faiss_index=faiss_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
documents = SimpleDirectoryReader("./uploaded_files").load_data()
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
index.storage_context.persist()
return "Done"
except:
return "Error"

The saveUploadedFiles function saves PDF documents uploaded by users to a designated directory (uploaded_files). The doVectorization function utilizes Faiss to vectorize these documents, making them searchable based on content similarities.

Speech Recognition and Transcription

def transcribe_audio():
recognizer = sr.Recognizer()
microphone = sr.Microphone()

with microphone as source:
recognizer.adjust_for_ambient_noise(source)
audio = recognizer.listen(source, timeout=20)

st.write("πŸ”„ Transcribing...")

try:
text = recognizer.recognize_google(audio)
return text
except sr.RequestError:
return "API unavailable or unresponsive"
except sr.UnknownValueError:
return "Unable to recognize speech"

The transcribe_audio function uses the speech_recognition library to capture spoken queries from users via their microphone. It adjusts for ambient noise and listens for up to 20 seconds before transcribing the speech into text using Google's speech recognition API.

Querying and Fetching Data

def fetchData(user_question):
try:
vector_store = FaissVectorStore.from_persist_dir("./storage")
storage_context = StorageContext.from_defaults(
vector_store=vector_store, persist_dir=PERSIST_DIR
)
index = load_index_from_storage(storage_context=storage_context)
query_engine = index.as_query_engine()
response = query_engine.query(user_question)
return str(response)
except:
return "Error"

The fetchData function retrieves relevant information from vectorized documents based on user queries. It loads the persisted Faiss index from storage and queries it to find and return the most relevant information matching the user's question.

Defining the Welcome Message

The WelcomeMessage variable contains a multi-line string that introduces users to the voice-enabled PDF chatbot. It encourages them to upload PDF documents and start asking questions:

WelcomeMessage = """
Hello, I am your PDF voice chatbot. Please upload your PDF documents and start asking questions to me.
I would try my best to answer your questions from the documents.
"""

This message serves as the initial greeting when users interact with the chatbot, providing clear instructions on how to proceed.

Initializing Chat History and Azure Speech SDK Configuration

The code block initializes the chat history and sets up configurations for Azure Speech SDK:

if "chat_history" not in st.session_state:
st.session_state.chat_history = [
AIMessage(content=WelcomeMessage)
]

AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION")
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

speech_config = speechsdk.SpeechConfig(subscription=AZURE_SPEECH_KEY, region=AZURE_SPEECH_REGION)
speech_config.speech_synthesis_voice_name = "en-US-AriaNeural"
speech_config.speech_synthesis_language = "en-US"

speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config)
  • Chat History Initialization: Checks if chat_history exists in the Streamlit session state. If not, it initializes it with the WelcomeMessage wrapped in an AIMessage object. This ensures that the chat starts with the welcome message displayed to the user.
  • Azure Speech SDK Configuration: Retrieves Azure Speech API key and region from environment variables (AZURE_SPEECH_KEY and AZURE_SPEECH_REGION). It sets up a SpeechConfig object for speech synthesis (speech_synthesizer). The voice name and language are configured to use the "en-US-AriaNeural" voice for English (US).

Streamlit Integration: User Interface Design

def main():
load_dotenv()

st.set_page_config(
page_title="Chat with multiple PDFs",
page_icon=":sparkles:"
)

st.header("Chat with single or multiple PDFs :sparkles:")

for message in st.session_state.chat_history:
if isinstance(message, AIMessage):
with st.chat_message("AI"):
st.markdown(message.content)
elif isinstance(message, HumanMessage):
with st.chat_message("Human"):
st.markdown(message.content)

with st.sidebar:
st.subheader("Your documents")
pdf_docs = st.file_uploader(
"Upload your PDFs here and click on 'Process'",
accept_multiple_files=True
)

if st.button("Process"):
with st.spinner("Processing"):
IsFilesSaved = saveUploadedFiles(pdf_docs)
if IsFilesSaved == "Done":
IsVectorized = doVectorization()
if IsVectorized == "Done":
st.session_state.isPdfProcessed = "done"
st.success("Done!")
else:
st.error("Error! in vectorization")
else:
st.error("Error! in saving the files")

if st.button("Start Asking Question"):
st.write("🎀 Recording started...Ask your question")
transcription = transcribe_audio()
st.write("✅ Recording ended")

st.session_state.chat_history.append(HumanMessage(content=transcription))

with st.chat_message("Human"):
st.markdown(transcription)

with st.chat_message("AI"):
with st.spinner("Fetching data ..."):
response = fetchData(transcription)
st.markdown(response)

result = speech_synthesizer.speak_text_async(response).get()
st.session_state.chat_history.append(AIMessage(content=response))

if "WelcomeMessage" not in st.session_state:
st.session_state.WelcomeMessage = WelcomeMessage
result = speech_synthesizer.speak_text_async(WelcomeMessage).get()

#============================================================================================================
if __name__ == '__main__':
main()

User Experience: Seamless Interaction

Imagine uploading a collection of PDF documents — research papers, technical manuals, or reports — and simply speaking your questions aloud. The chatbot not only transcribes your speech but also responds audibly, providing immediate access to relevant information. This seamless interaction is particularly beneficial for users with visual impairments or those multitasking who prefer auditory information consumption.

Demo πŸ’¬πŸŽ€πŸ€–


 

Enhancing Accessibility and Efficiency

Our voice-enabled PDF chatbot represents a significant advancement in accessibility technology. By integrating speech recognition, document vectorization, and AI-driven query processing, we empower users to effortlessly interact with complex information. This technology not only enhances accessibility but also boosts efficiency by streamlining the process of retrieving information from documents.

Conclusion: Paving the Way Forward

As we continue to explore the capabilities of AI in enhancing user experiences, the voice-enabled PDF chatbot stands as a testament to innovation in accessibility and usability. Whether you’re a researcher seeking insights from academic papers or a professional referencing technical documents, this technology promises to revolutionize how we interact with information.

Stay tuned as we push the boundaries further, exploring new applications and advancements in AI-driven technology. Stay connected and yes Happy Coding ! 😊

13 June, 2024

πŸš€ Revolutionizing Document Interaction: An AI-Powered PDF Text-2-Voice Chatbot Using LlamaIndex πŸ‘, Langchain πŸ”— and Azure AI Speech πŸ”Š

 In this blog post, we’re diving into the creation of an intelligent PDF voice chatbot using cutting-edge technologies like LangChain, LlamaIndex, and Azure AI Speech. This isn’t just another chatbot; it’s an interactive voice assistant capable of understanding and reading out the answer from the content in your PDFs. This project is a step up from my previous blog post where we explored building a text-based PDF chatbot without the voice functionality. If you missed that, be sure to check it out here

Technologies Used

  1. LangChain: For chaining language models and building complex applications.
  2. LlamaIndex: To index and query documents efficiently.
  3. Azure AI Speech: For speech synthesis, giving our bot a human-like voice.
  4. Streamlit: To create a user-friendly web interface.

Let’s jump into the code and see how these technologies come together to create our voice assistant chatbot.

Setting Up the Environment

First, ensure you have all the necessary libraries installed. You can do this by running:

pip install os faiss-cpu streamlit python-dotenv azure-cognitiveservices-speech langchain llama_index

Also, make sure you have your Azure Cognitive Services API keys ready.

The Code

Here’s the complete code for our voice chatbot:

import os
import faiss
import streamlit as st
from dotenv import load_dotenv
from langchain_core.messages import AIMessage, HumanMessage
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, load_index_from_storage
from llama_index.vector_stores.faiss import FaissVectorStore
import azure.cognitiveservices.speech as speechsdk

d = 1536
faiss_index = faiss.IndexFlatL2(d)
PERSIST_DIR = "./storage"

AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION")
OPENAI_API_KEY=os.getenv("OPENAI_API_KEY")

def saveUploadedFiles(pdf_docs):
UPLOAD_DIR = 'uploaded_files'
try:
for pdf in pdf_docs:
file_path = os.path.join(UPLOAD_DIR, pdf.name)
with open(file_path, "wb") as f:
f.write(pdf.getbuffer())
return "Done"
except:
return "Error"

def doVectorization():
try:
vector_store = FaissVectorStore(faiss_index=faiss_index)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
documents = SimpleDirectoryReader("./uploaded_files").load_data()
index = VectorStoreIndex.from_documents(
documents,
storage_context=storage_context
)
index.storage_context.persist()
return "Done"
except:
return "Error"

def fetchData(user_question):
try:
vector_store = FaissVectorStore.from_persist_dir("./storage")
storage_context = StorageContext.from_defaults(
vector_store=vector_store, persist_dir=PERSIST_DIR
)
index = load_index_from_storage(storage_context=storage_context)
query_engine = index.as_query_engine()
response = query_engine.query(user_question)
return str(response)
except:
return "Error"

WelcomeMessage = """
Hello, I am your PDF voice chatbot. Please upload your PDF documents and start asking questions.
I will try my best to answer your questions based on the documents.
"""


if "chat_history" not in st.session_state:
st.session_state.chat_history = [
AIMessage(content=WelcomeMessage)
]

AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION")
os.environ["OPENAI_API_KEY"] = os.getenv("OPENAI_API_KEY")

speech_config = speechsdk.SpeechConfig(subscription=AZURE_SPEECH_KEY, region=AZURE_SPEECH_REGION)
speech_config.speech_synthesis_voice_name = "en-US-AriaNeural"
speech_config.speech_synthesis_language = "en-US"

speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config)

def main():
load_dotenv()

st.set_page_config(
page_title="Chat with multiple PDFs",
page_icon=":sparkles:"
)

st.header("Chat with single or multiple PDFs :sparkles:")

for message in st.session_state.chat_history:
if isinstance(message, AIMessage):
with st.chat_message("AI"):
st.markdown(message.content)
elif isinstance(message, HumanMessage):
with st.chat_message("Human"):
st.markdown(message.content)

with st.sidebar:
st.subheader("Your documents")
pdf_docs = st.file_uploader(
"Upload your PDFs here and click on 'Process'",
accept_multiple_files=True
)

if st.button("Process"):
with st.spinner("Processing"):
IsFilesSaved = saveUploadedFiles(pdf_docs)
if IsFilesSaved == "Done":
IsVectorized = doVectorization()
if IsVectorized == "Done":
st.session_state.isPdfProcessed = "done"
st.success("Done!")
else:
st.error("Error! in vectorization")
else:
st.error("Error! in saving the files")

user_question = st.chat_input("Ask a question about your document(s):")

if user_question is not None and user_question != "":
st.session_state.chat_history.append(HumanMessage(content=user_question))

with st.chat_message("Human"):
st.markdown(user_question)

with st.chat_message("AI"):
with st.spinner("Fetching data ..."):
response = fetchData(user_question)
st.markdown(response)

result = speech_synthesizer.speak_text_async(response).get()
st.session_state.chat_history.append(AIMessage(content=response))

if "WelcomeMessage" not in st.session_state:
st.session_state.WelcomeMessage = WelcomeMessage
result = speech_synthesizer.speak_text_async(WelcomeMessage).get()

if __name__ == '__main__':
main()

Breaking Down the Code

Environment Setup

We start by importing necessary libraries and loading environment variables using dotenv. The .env file :

OPENAI_API_KEY = ""
AZURE_OPENAI_API_KEY = ""
AZURE_SPEECH_KEY = ""
AZURE_SPEECH_REGION = ""

File Upload and Vectorization

The saveUploadedFiles function handles file uploads, saving PDFs to a directory. The doVectorization function uses Llama_Index and FAISS to create a searchable index from the uploaded documents.

Fetching Data

The fetchData function retrieves answers to user questions by querying the vector index.

Voice Synthesis

We use Azure AI Speech service to convert text responses into speech. This involves configuring the speechsdk.SpeechConfig and synthesizing speech with speechsdk.SpeechSynthesizer.

Streamlit Interface

Streamlit makes it easy to build a web interface. The sidebar allows users to upload and process PDFs. The main chat interface displays the conversation and handles user inputs.

Running the App

Run the Streamlit app using:

streamlit run your_script_name.py

Upload your PDF documents, ask questions, and listen as the bot responds with both text and voice.


 

Conclusion

By combining LangChain, LlamaIndex, and Azure AI, we’ve created an intelligent PDF voice chatbot that can make interacting with documents more engaging and accessible. Whether you’re using it for research, studying, or just exploring, this project showcases the potential of modern AI and NLP technologies.

Don’t forget to check out the previous blog post for a text-only version of this chatbot. Happy coding!

30 May, 2024

Integrating Azure Cognitive Services with OpenAI for interactive Voice-based AI Responses πŸ€–πŸŽ€

In today's fast-moving digital world, mixing top-notch AI tech is opening up endless chances for cool experiences. When we combine Azure Cognitive Services, which are really good at understanding speech, with OpenAI, which is great at understanding natural language, magic happens. It lets us make AI systems that talk back to us in real time, understanding what we say like it's second nature. Jump into the world where Azure meets OpenAI, and see how it's changing the way we interact with computers.

In this blog post, we’ll explore a Python script that achieves this integration, enabling a fully interactive voice-based AI system.


Overview

The script leverages Azure’s Speech SDK to recognize spoken language and OpenAI’s language model to generate responses. The process involves several key steps:

  1. Loading Environment Variables: Using dotenv to manage API keys securely.
  2. Configuring Azure Speech SDK: Setting up speech recognition and synthesis.
  3. Invoking OpenAI API: Using the recognized speech to generate a response.
  4. Synthesizing AI Response: Converting the AI-generated text back to speech.

Let’s delve into the details.

Prerequisites

Before you start, ensure you have the following:

  • Azure Cognitive Services subscription with Speech API.
  • OpenAI API key.
  • Python environment with necessary libraries installed (azure-cognitiveservices-speech, python-dotenv, langchain_openai).

Code Walkthrough

Below is the complete script with comments to guide you through each section:

import os
from dotenv import load_dotenv
import azure.cognitiveservices.speech as speechsdk
from langchain_openai import OpenAI

# Load environment variables from a .env file
load_dotenv()

# Retrieve API keys from environment variables
AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION")
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")

# Initialize the OpenAI language model with the API key
llm = OpenAI(api_key=OPENAI_API_KEY)

# Configure Azure Speech SDK for speech recognition
speech_config = speechsdk.SpeechConfig(subscription=AZURE_SPEECH_KEY, region=AZURE_SPEECH_REGION)
speech_config.speech_recognition_language = "en-US"

# Set up the audio input from the default microphone
audio_config = speechsdk.audio.AudioConfig(use_default_microphone=True)
speech_recognizer = speechsdk.SpeechRecognizer(speech_config=speech_config, audio_config=audio_config)

print("You can speak now. I am listening ...")

# Start speech recognition
speech_recognition_result = speech_recognizer.recognize_once_async().get()

# Check the result of the speech recognition
if speech_recognition_result.reason == speechsdk.ResultReason.RecognizedSpeech:
output = speech_recognition_result.text
print(output) # User question

# Invoke the OpenAI API with the recognized speech text
result = llm.invoke(output)
print(result) # AI Answer

# Configure audio output for speech synthesis
audio_config = speechsdk.audio.AudioOutputConfig(use_default_speaker=True)
speech_synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=audio_config)

# Synthesize the AI response into speech
speech_synthesizer_result = speech_synthesizer.speak_text_async(result).get()

elif speech_recognition_result.reason == speechsdk.ResultReason.NoMatch:
print("No speech could be recognized: {}".format(speech_recognition_result.no_match_details))

elif speech_recognition_result.reason == speechsdk.ResultReason.Canceled:
cancellation_details = speech_recognition_result.cancellation_details
print("Speech Recognition canceled: {}".format(cancellation_details.reason))
if cancellation_details.reason == speechsdk.CancellationReason.Error:
print("Error details: {}".format(cancellation_details.error_details))

Step-by-Step Breakdown

1. Loading Environment Variables

Using the dotenv package, we load sensitive API keys from a .env file, ensuring they are not hard-coded in the script.

2. Configuring Azure Speech SDK

We set up the Azure Speech SDK with the necessary subscription key and region. This configuration allows the SDK to access Azure’s speech recognition services.

3. Speech Recognition

The SpeechRecognizer object listens for speech input via the default microphone and processes the speech to text asynchronously. Upon recognition, it checks the result and extracts the recognized text.

4. Invoking OpenAI API

The recognized text is then passed to OpenAI’s language model, which generates a relevant response. This integration allows for dynamic interaction, where the AI can understand and respond contextually.

5. Speech Synthesis

Finally, the AI-generated text response is synthesized back into speech using Azure’s SpeechSynthesizer, providing a spoken response through the default speaker.

Error Handling

The script includes basic error handling for different outcomes of the speech recognition process:

  • RecognizedSpeech: When speech is successfully recognized.
  • NoMatch: When no speech is recognized.
  • Canceled: When the recognition process is canceled, potentially due to errors.

Conclusion

Integrating Azure Cognitive Services with OpenAI creates a powerful platform for developing interactive voice applications. This combination leverages the robust speech recognition and synthesis capabilities of Azure with the advanced natural language understanding of OpenAI. Whether for virtual assistants, customer support, or other innovative applications, this integration showcases the potential of modern AI technologies.

Feel free to experiment with the code and adapt it to your specific use case. The possibilities are endless when combining these advanced tools in creative ways.