Building an LLM Application for Document Q&A Using Chainlit, Qdrant and Zephyr
This blog presents an application utilizing the Zephyr-7B Beta model as the Large Language Model, along with Langchain and Chainlit. Here, I will investigate their respective capabilities and showcase their potential in the development of an interactive chat application. I will outline the design of the user interface (UI), the establishment of backend processing, and the seamless integration processes involved in creating a fully operational Question-Answering App.
Step-by-Step Implementation
- Document Submission: Begin by uploading the required document in PDF format, ensuring an accurate submission.
- Text Extraction with PyPDF2: Utilize the PyPDF2 utility to proficiently extract textual content from the uploaded PDF document, ensuring precision in extraction.
- Semantic Representation with HuggingFace Embeddings: Employ the OpenAIEmbeddings mechanism to transform the extracted text into vectorized embeddings, quantitatively encapsulating the semantic essence of the content.
- Vector Storage in Qdrant: Securely store vectorized embeddings in Qdrant, establishing an organized and retrievable repository of semantic representations.
- Query Vectorization with HuggingFace Embeddings: Convert user queries into corresponding vector embeddings using OpenAIEmbeddings, aligning the query’s semantic structure into the vectorized domain.
- Contextual Document Retrieval: Utilize vectorized embeddings of the query to efficiently retrieve documents with contextual similarity, while gathering pertinent metadata to enrich document context.
- Reranking the context retrieved: Instead of immediately returning retrieved documents as-is, you can compress them using the context of the given query, so that only the relevant information is returned.
- Generative AI System Integration: Pass the collated set of retrieved documents and their metadata to a generative AI system. Trigger an advanced cognitive process to craft informative responses based on contextual insights from the documents.
- User Response Synthesis: Conclude the sequence by transmitting the synthesized answer, generated by the generative AI system, back to the user as a thoughtful and comprehensive response that aptly addresses the inquiries posed in the original query.
This experiment demonstrates the practical implementation of Zephyr-7B-Beta and advanced AI technologies in creating a sophisticated Question Answering App, showcasing the potential for enhanced user interactions and cognitive responses.
The Technology Stack
- Qdrant: Vector store for storing text embeddings.
- BAAI/bge-small-en-v1.5: Embedding model facilitating advanced semantic analysis.
- Langchain: Framework for application development using Large Language Models (LLMs).
- Chainlit: Interface builder, facilitating the creation of ChatGPT-like interfaces.
- Zephyr-7B Beta: Large Language Model serving as the core component in the application.
- Cohere Re-Ranker: Enhances relevance through reranking retrieved context. Utilizes Cohere’s rerank endpoint for improved human-machine interactions.
- Contextual Compression: Addresses challenges in retrieval by compressing and filtering documents based on query context. Involves a base retriever and a document compressor in the retrieval process.
This integration of technologies presents a robust framework for developing interactive chat applications with advanced question-answering capabilities. The outlined steps and technology stack collectively contribute to a seamless and efficient user experience.
An Overview of Zephyr-7B Beta
Zephyr Beta stands as a refined 7B iteration of the Mistral Large Language Model, meticulously trained on a blend of publicly accessible and synthetic datasets. Boasting 7 billion parameters, Zephyr has undergone fine-tuning on Mistral to yield outcomes comparable to Llama 2 70B Chat across various benchmarks (ARC, HellaSwag, MMLU, and TruthfulQA).
This model not only surpasses its larger counterparts, such as the GPT-3.5 Turbo and Llama 70B, but also challenges the capabilities of GPT-4 in the Alpaca benchmarks, all while maintaining a more compact form, being 25 times smaller than the GPT-3.5 model.
Both Zephyr-7B Beta and ChatGPT share the common objective of acting as valuable assistants for educational and research purposes. However, they diverge in their methodologies. Zephyr-7B Beta demonstrates versatility in addressing a broad spectrum of queries, drawing insights from web data and technical sources. In contrast, ChatGPT employs a slightly different training approach and utilizes distinct datasets.
The success of Zephyr-7B Beta can be attributed, in part, to its fine-tuning through direct distillation. This involves leveraging model completions based on chosen rewards and AI feedback, resulting in superior alignment with human preferences. An additional distinctive feature of Zephyr-7B Beta is its tokenizer’s chat template, which contributes to the generation of more precise responses.
Notably, Zephyr-7B Beta exhibits commendable performance on modern CPUs, delivering satisfactory results.
An Overview of Chainlit
Chainlit, an open-source Python package, expedites the development of ChatGPT-like applications by seamlessly integrating business logic and data.
Key attributes include:
- Swift Construction: Easily integrate into an existing codebase or initiate development from scratch within minutes.
- Data Continuity: Utilize user-generated data and feedback to enhance application performance.
- Visualizing Complex Reasoning: Gain insights into the intermediate steps leading to specific outcomes with a quick overview.
- Prompt Refinement: Delve deep into prompts within the Prompt Playground to identify issues and iterate for improvement.
Integrations available:
- Langchain
- Haystack
- LLama-Index
- Langflow
For the RAG implementation illustrated here, the Langchain framework will be utilized.
Explaining the Langchain Framework
Langchain, a freely available framework, streamlines the development of applications utilizing Large Language Models (LLMs). It provides:
- Standardized Interface: Furnishes a standardized interface for chains, facilitating seamless integration with various tools.
- Complete Chains: Offers complete chains tailored for prevalent applications, enabling AI developers to leverage the power of LLMs like GPT-4 alongside external sources of computation and data.
- Cross-Language Support: Accompanied by packages for both Python and JavaScript.
Vector Store Explained
Definition
Vector stores are specialized databases designed for efficient storage and retrieval of vector embeddings. This specialization is crucial, as conventional databases like SQL are not finely tuned for handling extensive vector data.
Role of Embeddings
Embeddings represent data, typically unstructured data like text, in numerical vector formats within a high-dimensional space. Traditional relational databases are ill-suited for storing and retrieving these vector representations.
Key Features of Vector Stores
- Efficient Indexing: Vector stores can index and rapidly search for similar vectors using similarity algorithms.
- Enhanced Retrieval: This functionality allows applications to identify related vectors based on a provided target vector query.
An Overview of Qdrant
Qdrant is a specialized vector similarity search engine designed to offer a production-ready service through a user-friendly API. It facilitates the storage, search, and management of points (vectors) along with additional payloads. These payloads serve as supplementary pieces of information, enhancing the precision of searches and providing valuable data to users.
Getting started with Qdrant is seamless. Utilize the Python qdrant-client, access the latest Docker image of Qdrant and establish a local connection, or explore Qdrant’s Cloud free tier option until you are prepared for a comprehensive transition.
High-Level Qdrant Architecture
Understanding Semantic Similarity
Semantic similarity, in the context of a set of documents or terms, is a metric that gauges the distance between items based on the similarity of their meaning or semantic content, rather than relying on lexicographical similarities. This involves employing mathematical tools to assess the strength of the semantic relationship between language units, concepts, or instances. The numerical description obtained through this process results from comparing the information that supports their meaning or describes their nature.
It’s crucial to distinguish between semantic similarity and semantic relatedness. Semantic relatedness encompasses any relation between two terms, whereas semantic similarity specifically involves ‘is a’ relation. This distinction clarifies the nuanced nature of semantic comparisons and their application in various linguistic and conceptual contexts.
What Is Re-Ranking
Re-ranking in technical search processes involves a two-stage process known as RAG:
Stage 1 — Keyword Search
Stage 2 — Semantic-Based Top-k Retrieval
In traditional semantic search, a two-step approach is employed. Initially, a retrieval mechanism conducts an approximate sweep over a collection of documents, creating a preliminary document list. Subsequently, a re-ranker mechanism takes this candidate document list and reorganizes the elements. The re-ranking process enhances model performance by reorganizing results based on specific parameters.
Why Is Re-Ranking Essential?
The recall performance for Large Language Models (LLMs) tends to decrease with the addition of more context, leading to an expanded context window, or ‘context stuffing’. The fundamental concept behind re-ranking is to streamline the total number of documents into a fixed quantity. The re-ranker prioritizes and reorganizes records, placing the most relevant items at the top, which are then sent to the LLM. Re-ranking proves invaluable by identifying records that may not be within the top three results and consolidating them into a smaller set, subsequently fed into the LLM.
Introduction: Cohere Re-Ranker
Cohere, a Canadian start-up specializing in natural language processing models for improving human-machine interactions, offers a re-rank endpoint within their retriever. This builds upon concepts outlined in the Contextual Compression Retriever.
Understanding Contextual Compression
One challenge in document retrieval is the uncertainty of specific queries the document storage system will encounter during data ingestion. This often results in pertinent information being buried in documents containing irrelevant text. Transmitting entire documents through applications can lead to higher costs for LLM calls and suboptimal responses.
Contextual compression addresses this issue. The core idea involves not immediately returning retrieved documents as they are but compressing them using the context of the given query. This ensures that only relevant information is delivered.
The term ‘compressing’ in this context refers to both condensing the contents of individual documents and selectively filtering out documents wholesale.
Steps in Contextual Compression
To utilize the Contextual Compression Retriever, the following components are necessary:
- A Base Retriever.
- A Document Compressor.
The process involves the following steps:
- The Contextual Compression Retriever forwards queries to the base retriever.
- It then subjects the initial documents to the Document Compressor.
- The Document Compressor shortens the list of documents by either reducing the content of the documents or eliminating them entirely.
Install Required Dependencies
pip install langchain qdrant-client huggingface_hub sentence-transformers PyPDF2 cohere chainlit
pip install rank_bm25
pip install llama-cpp-python
Create a Project Folder
mkdir chainlit_rag
Create .env File with the Following Content Inside the Folder
[cohere]
api_key = Your COHERE API KEY1
You can obtain the API key by registering yourself at: https://dashboard.cohere.com/api-keys
Download the Model Parameter File
https://huggingface.co/TheBloke/zephyr-7B-beta-GGUF/blob/main/zephyr-7b-beta.Q4_K_M.gguf
Download the model file from the above link and save it to the current working directory, i.e., inside the chainlit_rag folder.
Code Implementation
This code is implemented using Python. It is part of a system designed for processing and answering user questions based on the content of uploaded PDF documents.
It uses various natural language processing and retrieval techniques. Let’s break down the key components and functionalities:
Libraries and Imports
- The code imports several libraries such as Langchain modules, Chainlit, PyPDF2, BytesIO, os, and ConfigParser.
- It uses classes and functions from these libraries for natural language processing, document retrieval, and system configuration.
Cohere API Key Configuration
- The code reads the Cohere API key from a configuration file (.env) and sets it as an environmental variable.
Text Chunking and Processing
- Text from a PDF file is split into chunks using a RecursiveCharacterTextSplitter with specified parameters.
- The code then processes the PDF text, creating metadata for each chunk and storing it in a Chroma vector store.
Language Models and Retrievers
- The code uses language models from HuggingFaceBgeEmbeddings for embedding text.
- Retrieval models like BM25Retriever and Ensemble Retriever are employed to retrieve relevant documents based on user queries.
- A Cohere Rerank component is used for re-ranking retrieved documents to improve response quality.
Initialization and User Interaction
- The system prompts the user to upload a PDF file and processes it upon receiving the file.
- It sets up various components, including language models, retrievers, and compressors.
- The system notifies the user that the document has been processed, and they can now ask questions.
Message Templates and System Initialization
- The system uses message templates for system prompts and human messages.
- A system message template guides users on how to answer questions and requests, returning sources in responses.
WebSocket Event Handlers
- The code includes decorators (@cl.on_chat_start and @cl.on_message) for handling websocket events.
- Upon the user’s connection, the system initializes and waits for a PDF file upload.
- The code reacts to user messages, processes them using the defined chain of components, and sends responses back to the user.
User Session Management
- The code utilizes the Chainlit cl.user_session to store and retrieve user-specific data during the interaction.
- It stores metadata, texts, and the processing chain in the user session for later use.
Final Answer Presentation
- The system retrieves and presents the final answer to the user’s question along with relevant source documents.
- It handles cases where the final answer is streamed and updates the UI accordingly.
Overall, this code orchestrates a complex system for processing PDF documents, retrieving relevant information, and providing thoughtful answers to user queries through a websocket interface.
Sample Code
Create app.py file inside the chainlit_rag folder and paste the code illustrated below.
Import Required Dependencies
#import required libraries
from langchain.embeddings import HuggingFaceEmbeddings,HuggingFaceBgeEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Qdrant
from langchain.chains import RetrievalQAWithSourcesChain,RetrievalQA
from langchain.chat_models import ChatOpenAI
from langchain.prompts.chat import (ChatPromptTemplate,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate)
from langchain.llms import CTransformers
from langchain.llms import LlamaCpp
from langchain.retrievers import BM25Retriever,EnsembleRetriever
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import CohereRerank
from cohere import Client
#
import chainlit as cl
import PyPDF2
from io import BytesIO
from getpass import getpass
#
import os
from configparser import ConfigParser
env_config = ConfigParser()
Retrieve the Cohere API Keys from .env File
# Retrieve the cohere api key from the environmental variables
def read_config(parser: ConfigParser, location: str) -> None:
assert parser.read(location), f"Could not read config {location}"
#
CONFIG_FILE = os.path.join(".", ".env")
read_config(env_config, CONFIG_FILE)
api_key = env_config.get("cohere", "api_key").strip()
os.environ["COHERE_API_KEY"] = api_key
Chunk the Texts Retrieved into Smaller Chunks with Overlap
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=100)
Create a System Template in Order to Instruct the LLM
system_template = """Use the following pieces of context to answer the user's question.
If you don't know the answer, just say that you don't know, don't try to make up an answer.
ALWAYS return a "SOURCES" part in your answer.
The "SOURCES" part should be a reference to the source of the document from which you got your answer.
Begin!
- - - - - - - -
{summaries}"""
messages = [SystemMessagePromptTemplate.from_template(system_template),HumanMessagePromptTemplate.from_template("{question}"),]
prompt = ChatPromptTemplate.from_messages(messages)
chain_type_kwargs = {"prompt": prompt}
Chainlit inherently supports asynchronous operations, enabling agents to perform tasks simultaneously and facilitating multiple users to engage with a single app. This approach of asynchronous programming is an effective method to manage multiple tasks at once, allowing the program to run without interruption or blocking.
The async and await keywords are used to define and work with asynchronous code in Python. An async function is a co-routine, which is a special type of function that can pause its execution and resume later, allowing other tasks to run in the meantime.
Chainlit uses asynchronous programming to handle events and tasks efficiently. When creating a Chainlit agent, we often need to define async functions to handle events and perform actions.
Helper Function to Define Tasks to Be Initialized on Start of the User Chat Session
#Decorator to react to the user websocket connection event.
@cl.on_chat_start
async def init():
files = None
# Wait for the user to upload a PDF file
while files is None:
files = await cl.AskFileMessage(
content="Please upload a PDF file to begin!",
accept=["application/pdf"],
).send()
file = files[0]
msg = cl.Message(content=f"Processing `{file.name}`…")
await msg.send()
# Read the PDF file
pdf_stream = BytesIO(file.content)
pdf = PyPDF2.PdfReader(pdf_stream)
pdf_text = ""
for page in pdf.pages:
pdf_text += page.extract_text()
# Split the text into chunks
texts = text_splitter.split_text(pdf_text)
# Create metadata for each chunk
metadatas = [{"source": f"{i}-pl"} for i in range(len(texts))]
# Create a Chroma vector store
model_id = "BAAI/bge-small-en-v1.5"
embeddings = HuggingFaceBgeEmbeddings(model_name= model_id,
model_kwargs = {"device":"cpu"})
#
bm25_retriever = BM25Retriever.from_texts(texts)
bm25_retriever.k=5
# Store the embeddings in the user session
cl.user_session.set("embeddings", embeddings)
docsearch = await cl.make_async(Qdrant.from_texts)(
texts, embeddings,location=":memory:", metadatas=metadatas
)
llm = LlamaCpp(streaming=True,
model_path="zephyr-7b-beta.Q4_K_M.gguf",
max_tokens = 1500,
temperature=0.75,
top_p=1,
gpu_layers=0,
stream=True,
verbose=True,n_threads = int(os.cpu_count()/2),
n_ctx=4096)
#Hybrid Search
qdrant_retriever = docsearch.as_retriever(search_kwargs={"k":5})
ensemble_retriever = EnsembleRetriever(retrievers=[bm25_retriever,qdrant_retriever],
weights=[0.5,0.5])
#Cohere Reranker
#
compressor = CohereRerank(client=Client(api_key=os.getenv("COHERE_API_KEY")),user_agent='langchain')
#
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor,
base_retriever=ensemble_retriever,
)
# Create a chain that uses the Chroma vector store
chain = RetrievalQA.from_chain_type(
llm = llm,
chain_type="stuff",
retriever=compression_retriever,
return_source_documents=True,
)
# Save the metadata and texts in the user session
cl.user_session.set("metadatas", metadatas)
cl.user_session.set("texts", texts)
# Let the user know that the system is ready
msg.content = f"`{file.name}` processed. You can now ask questions!"
await msg.update()
#store the chain as long as the user session is active
cl.user_session.set("chain", chain)
Helper Function to React to Messages Coming from the UI
@cl.on_message
async def process_response(res:cl.Message):
# retrieve the retrieval chain initialized for the current session
chain = cl.user_session.get("chain")
# Chinlit callback handler
cb = cl.AsyncLangchainCallbackHandler(
stream_final_answer=True, answer_prefix_tokens=["FINAL", "ANSWER"])
cb.answer_reached = True
print("in retrieval QA")
#res.content to extract the content from chainlit.message.Message
print(f"res : {res.content}")
response = await chain.acall(res.content, callbacks=[cb])
print(f"response: {response}")
answer = response["result"]
sources = response["source_documents"]
source_elements = []
# Get the metadata and texts from the user session
metadatas = cl.user_session.get("metadatas")
all_sources = [m["source"] for m in metadatas]
texts = cl.user_session.get("texts")
if sources:
found_sources = []
# Add the sources to the message
for source in sources:
print(source.metadata)
try :
source_name = source.metadata["source"]
except :
source_name = ""
# Get the index of the source
text = source.page_content
found_sources.append(source_name)
# Create the text element referenced in the message
source_elements.append(cl.Text(content=text, name=source_name))
if found_sources:
answer += f"\nSources: {', '.join(found_sources)}"
else:
answer += "\nNo sources found"
if cb.has_streamed_final_answer:
cb.final_stream.elements = source_elements
await cb.final_stream.update()
else:
await cl.Message(content=answer, elements=source_elements).send()
Execute the Chainlit Script
Please type the below command in the command prompt to invoke the chainlit application.
chainlit run app.py
Chainlit User Interface Snapshots
Snapshot 1
System run logs
in retrieval QA
Batches: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████| 1/1 [00:00<00:00, 41.66it/s]
response: {'query': 'What is the social stigma associated with Mental Health?', 'result': " Social stigma refers to the negative attitudes, beliefs, and behaviors that society assigns to individuals with mental illness. It can lead to exclusion, prejudice, and discrimination, which in turn can affect an individual's self-esteem, social relationships, and access to opportunities and resources. Stigma is a worldwide phenomenon and continues to be a significant barrier for people seeking help for their mental health concerns. Themes associated with mental illness and stigma include beliefs that individuals with mental illness are dangerous, unpredictable, to blame for their condition, difficult to communicate with, and have poor treatment outcomes. This can lead to personal fear in others, exclusion, prejudice, and discrimination against those with mental illness.", 'source_documents': [Document(page_content='In this section the aim is to explore the concepts of, and the relationship between, stigma and mental illness. One possible reason for both conceptual confusion and reluctance to seek help is that the stigmatization of mental illness continues to be a worldwide phenomenon (Jorm et al.\n1997; Crisp et al. 2000; Sartorius 2002; Gureje et al. 2005).\nDefinition of the concept of stigma\nStigma can be viewed as a social construct. Setting people apart from other members of society has a long history. In ancient Greece members of tainted groups - for example, slaves andDefining mental health and mental illness 11 traitors - were branded with a mark (Goffman 1970; Hinshaw 2005). The concept is applied in\ndiverse circumstances, including with reference to the mentally ill (Link and Phelan 2001).Additionally, stigmatization can be seen to depend on social, economic and political power andcan occur on a large and tragic scale - for example, the systematic and dreadful stigmatization', metadata={'source': '19-pl', 'relevance_score': 0.9789956}), Document(page_content='Box 1.2 Themes associated with mental illness and stigma identi fied\nby adolescents\n•Negative attitudes towards groups described as deviant - for example, the mentally\nill - were apparent by kindergarten and increased with age (Weiss 1986, 1994;\nWahl 2002).Defining mental health and mental illness 13•Words and phrases used to describe people with mental health problems or\nmental illness were largely derogatory, with the most common labels being'retarded ', 'psycho(path) ', 'spastic ', 'mental ', 'crazy ' and 'nutter ' (Bailey 1999;\nPinfold et al. 2003).\n•The most frequently cited causes of mental illness were stress, genetics and bad\nchildhood experiences (Bailey 1999).\n•Y oung people with experience of mental health problems described being met\nwith negative attitudes and reactions from other people, including professionals(Scottish Executive 2005).\n•Although adolescents stigmatized peers with both physical and mental illness,', metadata={'source': '28-pl', 'relevance_score': 0.97631055}), Document(page_content='These explanations can be elaborated as follows: people with mental illness are perceived as\ndangerous and unpredictable; there is an implied belief that the mentally ill choose to behaveas they do and have only themselves to blame for their situation; people with mental illnessare believed to respond poorly to treatment, and outcomes are poor, therefore they are anembarrassment and should be avoided; the mentally ill are seen as dif ficult to communicate\nwith and this makes for unpredictable social intercourse. These are enduring themes, provoking personal fear in others and threatening to upset the status quo (Hayward and Bright 1997;Eminson 2004).\nExplanations for the stigmatization of the mentally ill include the following ideas.\n\x7fFrom a biological perspective, a person suffering from mental illness may be viewed as a poor genetic choice in relation to reproductive potential and as a possible threat to the safety of the individual.', metadata={'source': '22-pl', 'relevance_score': 0.9651191})]}
{'source': '19-pl', 'relevance_score': 0.9789956}
{'source': '28-pl', 'relevance_score': 0.97631055}
{'source': '22-pl', 'relevance_score': 0.9651191}
Snapshot 2
System run logs
llama_print_timings: load time = 1093.50 ms
llama_print_timings: sample time = 37.26 ms / 130 runs ( 0.29 ms per token, 3488.81 tokens per second)
llama_print_timings: prompt eval time = 94385.15 ms / 808 tokens ( 116.81 ms per token, 8.56 tokens per second)
llama_print_timings: eval time = 27183.79 ms / 130 runs ( 209.11 ms per token, 4.78 tokens per second)
llama_print_timings: total time = 122202.95 ms
response: {'query': 'What are the Themes associated with mental illness and stigma identified\nby adolescents?', 'result': ' According to Box 1.2 in the text, some themes associated with mental illness and stigma identified by adolescents include negative attitudes toward groups described as deviant, such as those with mental health problems, increasing with age; derogatory labels used to describe people with mental health problems or mental illness, such as "retarded," "psycho(path)," "spastic," "mental," "crazy," and "nutter"; stress, genetics, and bad childhood experiences as frequently cited causes of mental illness; and negative attitudes and reactions from other people, including professionals, towards individuals with mental health problems.', 'source_documents': [Document(page_content='Box 1.2 Themes associated with mental illness and stigma identi fied\nby adolescents\n•Negative attitudes towards groups described as deviant - for example, the mentally\nill - were apparent by kindergarten and increased with age (Weiss 1986, 1994;\nWahl 2002).Defining mental health and mental illness 13•Words and phrases used to describe people with mental health problems or\nmental illness were largely derogatory, with the most common labels being'retarded ', 'psycho(path) ', 'spastic ', 'mental ', 'crazy ' and 'nutter ' (Bailey 1999;\nPinfold et al. 2003).\n•The most frequently cited causes of mental illness were stress, genetics and bad\nchildhood experiences (Bailey 1999).\n•Y oung people with experience of mental health problems described being met\nwith negative attitudes and reactions from other people, including professionals(Scottish Executive 2005).\n•Although adolescents stigmatized peers with both physical and mental illness,', metadata={'source': '28-pl', 'relevance_score': 0.9996049}), Document(page_content='Children, mental illness and stigma\nThere is also a scarcity of research examining the issue of stigma in relation to children andmental illness (Wahl 2002; Hinshaw 2005). As described previously, the high prevalence ofmental health problems in young people and their reluctance to access specialist services givescause for concern. The indications are that children develop negative attitudes towards thosewith mental illness early on (Gale 2007). Additionally, adolescents are the adults of the futureand therefore their beliefs and attitudes regarding mental health and illness will affect servicedevelopment, the quality of life of those experiencing mental health problems and the help-seeking behaviour of individuals (Armstrong et al. 2000; Hinshaw 2005).\nBox 1.2 highlights themes identi fied from work which focused on adolescents, mental illness\nand stigma, albeit to varying degrees and using different methods.\nBox 1.2 Themes associated with mental illness and stigma identi fied', metadata={'source': '27-pl', 'relevance_score': 0.99843913}), Document(page_content='From the sparse literature available, it would appear that adolescents ' attitudes towards\nmental illness tend to be negative and stigmatizing. The need for education among the public,and adolescents in particular, in order to combat the stigma of mental illness is highlightedin the literature (Davidson and Manion 1996; Armstrong et al. 1998; Esters et al. 1998;\nBailey 1999; Secker et al. 1999; Taylor 2001; Naylor et al. 2002; Pow 2003; Hinshaw 2005;\nSessa 2005b).\nEarly indicators from our own work in Nigeria are that such attitudes transcend culture\n(Dogra 2009). However, there is evidence that stigma can be tackled. We will now examinesome of the interventions undertaken to reduce stigma among children.\nInterventions to reduce stigma\nLarge-scale interventions, such as high profile campaigns, are often difficult to evaluate. In the\nUK there have been several such campaigns - for example, The Royal College of Psychiatrists '', metadata={'source': '30-pl', 'relevance_score': 0.9777138})]}
{'source': '28-pl', 'relevance_score': 0.9996049}
{'source': '27-pl', 'relevance_score': 0.99843913}
{'source': '30-pl', 'relevance_score': 0.9777138}