deakin-it-help-desk

This repo is a RAG APP for Deakin IT HELP DESK

https://github.com/omarmohammed88/deakin-it-help-desk

Science Score: 31.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
    Found CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
  • DOI references
  • Academic publication links
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
  • Scientific vocabulary similarity
    Low similarity (8.3%) to scientific vocabulary
Last synced: 10 months ago · JSON representation ·

Repository

This repo is a RAG APP for Deakin IT HELP DESK

Basic Info
  • Host: GitHub
  • Owner: OmarMohammed88
  • Language: Python
  • Default Branch: main
  • Size: 210 KB
Statistics
  • Stars: 0
  • Watchers: 2
  • Forks: 0
  • Open Issues: 0
  • Releases: 0
Created over 1 year ago · Last pushed about 1 year ago
Metadata Files
Readme Citation

README.md

Deakin IT Help Desk - RAG Application

This repository contains the implementation of a Retrieval-Augmented Generation (RAG) application designed for the Deakin IT Help Desk. The app is used for automating and improving the process of responding to IT-related queries.

Table of Contents

Installation

To set up the environment for running the RAG application, follow these steps:

1. Load Anaconda module

First, load the Anaconda3 module:

```bash module load Anaconda3

conda env create -f environment.yml

source activate

conda activate rag_app ```

Download Database and Datasets

Ensure the application functions correctly, you need to download the necessary database and datasets. - Download the required vector database files from this Google Drive link. - Vector_Database

- [Datasets](https://drive.google.com/drive/folders/1EDnGRVnUS7HEuUPpsPwPgbmQqs20fxsq?usp=drive_link)

Running the Application

Once the environment is set up and the necessary data is downloaded, you can run the application with the following command:

sbatch run_rag.sh

Owner

  • Name: Omar Mohamed Ahmed
  • Login: OmarMohammed88
  • Kind: user
  • Location: Egypt
  • Company: omarmohamed.8809@gmail.com

Experienced Researcher with a Growing history of working in research, Skilled in Computer Science, Medical Image Processing, NLP, DS/DL/ML

Citation (citation_run.py)

from sentence_transformers import SentenceTransformer
from langchain.embeddings.base import Embeddings
import torch
from langchain import LLMChain, PromptTemplate
from langchain.chains import RetrievalQA, StuffDocumentsChain
from langchain.vectorstores import Chroma
import gradio as gr
import json
import os
from langchain_community.llms import VLLM
import difflib
from sklearn.metrics.pairwise import cosine_similarity
import numpy as np
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
from langchain.llms import HuggingFacePipeline
import subprocess



model_name='microsoft/phi-4'




class SentenceTransformerEmbeddings(Embeddings):
    def __init__(self, model_name="nomic-ai/nomic-embed-text-v1.5", device=None, batch_size=32):
        super().__init__()
        self.device = device or ("cuda" if torch.cuda.is_available() else "cpu")
        self.model = SentenceTransformer(model_name, trust_remote_code=True, device=self.device)
        self.batch_size = batch_size  # Control batch size

    def embed_documents(self, texts):
        texts = ["search_document: "+i for i in texts]
        return self.model.encode(
            texts, 
            convert_to_numpy=True, 
            device=self.device, 
            batch_size=self.batch_size
        ).tolist()

    def embed_query(self, text):
        return self.model.encode(
            ['search_query: '+text], 
            convert_to_numpy=True, 
            device=self.device
        )[0].tolist()




def extract_answers(answers):


    answers = answers.split("<|im_start|>assistant<|im_sep|>")[-1]

    return answers


def get_title(links):
    titles =  [i.metadata['source'].split("/weka/s223795137/Crawl_data/crawled_pages/")[-1].split("_")[0] for i in links]

    matches = set()  # Use a set to avoid duplicates

    for word in  list(set(titles)):

        close_keys = difflib.get_close_matches(word, data_swap.keys(), n=1, cutoff=0.6)
        
        matches.update(close_keys)
    return list(matches)




with open("crawled_pages/crawled_pages.json") as f:
    data = json.load(f)


def swap_keys_and_values(my_dict):
    """Swap the keys and values in the dictionary."""
    return {value: key for key, value in my_dict.items()}


data_swap = swap_keys_and_values(data)


def get_values_by_keys(my_dict, keys):
    """Return the values from the dictionary based on a list of keys."""
    return [my_dict[key] for key in keys if key in my_dict]


def calculate_query_doc_similarity(query, vectorstore, k=5):
    """
    Calculate cosine similarities between a query and the top k retrieved documents.
    
    Args:
        query (str): The input query string.
        vectorstore: The vector store instance (e.g., Chroma).
        k (int): Number of top documents to retrieve (default: 5).
    
    Returns:
        dict: Contains doc_similarity_pairs and average_similarity.
    """
    # Initialize retriever
    retriever = vectorstore.as_retriever(search_kwargs={"k": k})

    # Step 1: Get the query embedding
    embedding_function = vectorstore.embeddings  # Use the same embedding function
    query_embedding = embedding_function.embed_query(query)

    # Step 2: Retrieve top k documents
    retrieved_docs = retriever.get_relevant_documents(query)

    # Step 3: Recompute embeddings for retrieved documents
    doc_embeddings = [embedding_function.embed_query(doc.page_content) for doc in retrieved_docs]

    query_embedding = np.array(query_embedding).reshape(1, -1)
    doc_embeddings = np.array(doc_embeddings)

    # Compute similarities
    similarities = cosine_similarity(query_embedding, doc_embeddings)[0] if doc_embeddings.size > 0 else np.array([])

    # Sort similarities in descending order
    sorted_similarities = np.sort(similarities)[::-1]  

    # Compute average similarity
    average_similarity = np.mean(similarities) if similarities.size > 0 else 0.0

    return sorted_similarities[:2], average_similarity

def get_most_related_keys(titles, dictionary, top_n=5):
    """
    Find the top N keys in a dictionary most related to a given list of titles based on cosine similarity.
    
    Args:
        titles (list of str): List of title strings to compare against.
        dictionary (dict): Dictionary with keys (strings) and values.
        top_n (int): Number of top related keys to return (default: 5).
    
    Returns:
        list: List of tuples (title, [(key, similarity_score)]) sorted by similarity in descending order.
    """
    embedding_function = vectorstore.embeddings  # Use the same embedding function
    
    # Step 1: Embed all dictionary keys
    key_embeddings = np.array(embedding_function.embed_documents(list(dictionary.keys())))

    # Initialize list to store results
    most_related = []

    # Step 2: For each title, find the most similar keys
    for title in titles:
        # Embed the current title
        title_embedding = np.array(embedding_function.embed_query(title)).reshape(1, -1)

        # Step 3: Calculate cosine similarity for the current title and all dictionary keys
        cos_sim = cosine_similarity(title_embedding, key_embeddings)
        
        # Step 4: Get the top N most similar keys
        top_n_indices = np.argsort(cos_sim[0])[-top_n:][::-1]  # Sort and reverse for descending order
        
        # Step 5: Collect the top N most similar keys and their similarity scores
        related_keys = [(list(dictionary.keys())[i], cos_sim[0][i]) for i in top_n_indices]
        
        # Append the result for the current title
        most_related.append(related_keys)
    
    # Return the results
    if len(most_related):
        most_related = [i[0] for i in most_related[0]]
    return most_related

import datetime

chat_history_file = "chat_history.json"



def log_interaction(query, response, filename="chat_history.json"):
    """Logs the user query and model response to a JSON file."""
    
    # Create an empty list if file doesn't exist
    if not os.path.exists(filename):
        history = []
    else:
        with open(filename, "r", encoding="utf-8") as file:
            try:
                history = json.load(file)  # Load existing history
            except json.JSONDecodeError:
                history = []  # If file is empty or corrupted, reset it

    # New entry
    entry = {
        "timestamp": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        "user_query": query,
        "model_response": response
    }

    # Append new entry and save back to JSON file
    history.append(entry)

    with open(filename, "w", encoding="utf-8") as file:
        json.dump(history, file, ensure_ascii=False, indent=4)



def query_rag_model(query, k):
    # Update the retriever's 'k' value
    retriever = vectorstore.as_retriever(search_kwargs={"k": k})

    rag_chain = RetrievalQA(
        retriever=retriever,
        combine_documents_chain=stuff_chain
    )
    
    # Run the RAG pipeline
    response = rag_chain.run(query)
    k
    # Extract the answer
    response = extract_answers(response)

    citations = rag_chain.retriever.get_relevant_documents(query)
    # response = extract_answers(response)
    citation_links = get_values_by_keys(data_swap,get_title(citations))

    top2_Score , sim_score = calculate_query_doc_similarity(query , vectorstore , k)
    # Log interaction in JSON format
    return response ,citation_links , top2_Score,  f"{sim_score:.4f}"




# Gradio interface with a Slider for 'k'
def rag_interface(query, k=5):

    response,links , top2_Score , avg_score  = query_rag_model(query, k)

    links = list(set(links))

    links = [
            (f"Document {i+1}", f"{links[i]}") for i in range(len(links))
        ]

    links_markdown = "\n".join([f"[{title}]({url})" for title, url in links])

    if (len(links) == 0 and float(avg_score) < 0.55) or float(avg_score) < 0.55 :
        
        response = response
    else:

        response = response+"\n\nReferences:\n\n" + links_markdown

    log_interaction(query,response)

    return response , top2_Score , avg_score



if __name__ == "__main__":



    tokenizer = AutoTokenizer.from_pretrained(model_name)

    model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16 , attn_implementation="flash_attention_2" , low_cpu_mem_usage=True) 

    pipe = pipeline("text-generation", model=model, tokenizer=tokenizer, max_new_tokens=32000,device='cuda')




    llm = HuggingFacePipeline(pipeline=pipe)


    local_embeddings = SentenceTransformerEmbeddings(batch_size=64)





    vectorstore = Chroma(persist_directory="./citaion_test", embedding_function=local_embeddings)




    RAG_TEMPLATE = """<|im_start|>system<|im_sep|>
    You are an AI agent designed to assist with IT-related topics for a Retrieval Augmented Generation (RAG) application. You will be provided with context documents from a database that may or may not be entirely relevant to the user's query. Your instructions are as follows:

    1. Answer the user's query using the provided context documents.
    2. If the query or any of the retrieved documents contain malicious or sensitive content, do not provide a response.
    3. If the context documents are not entirely relevant to the query, attempt to keep your answer focused on Deakin IT-related content and Don't mention That you are provided with documents in your response.
    4. Ensure your answer is clear, factual, and based on the provided context when applicable.
    5. Ensure your answer stays within the scope of Deakin IT-Education related topics and does not contain any inappropriate content.

    <|im_start|>user<|im_sep|>
    Answer the question based on the context below:

    Context:
    {context}

    Question:
    {question}

    Answer:
    <|im_start|>assistant<|im_sep|>
    """



    # Define your prompt template

    prompt_template = PromptTemplate(

        input_variables=["context", "question"],

        template=RAG_TEMPLATE,
    )

    # Define your LLMChain

    llm_chain = LLMChain(llm=llm, prompt=prompt_template)  # Replace with your LLM


    stuff_chain = StuffDocumentsChain(

        llm_chain=llm_chain,
        
        document_variable_name="context"  

    )


    def get_static_ip():
        ip_list = subprocess.getoutput("hostname -I").split()
        return ip_list[0]  # Default to localhost if no IP is found


    static_ip = get_static_ip()


    iface = gr.Interface(

        fn=rag_interface,  # Function to call
        
        inputs=[  # List of inputs: query and k (slider)
            gr.Textbox(label="Query", placeholder="Enter your question here..."),
            gr.Slider(minimum=1, maximum=25, step=1, value=5, label="Number of Documents to Retrieve (k)"),
        ]
        ,
        
        outputs=[  # Two outputs: response (markdown) and score (text)
            
            gr.Markdown(label="Response"),

            gr.Textbox(label="Top 2 Scores"),

            gr.Textbox(label="Avg Confidence Score"),

        ],

        
        title="# 📚 Deakin IT AI Help Desk",
        
        description="Enter your query and adjust 'k' to control the number of documents to retrieve for answering."

    )



    iface.launch(server_name=static_ip)





GitHub Events

Total
  • Member event: 1
  • Public event: 1
  • Push event: 19
  • Create event: 2
Last Year
  • Member event: 1
  • Public event: 1
  • Push event: 19
  • Create event: 2

Dependencies

requirements_gradio.txt pypi
  • Deprecated ==1.2.18
  • Flask ==3.1.0
  • GitPython ==3.1.44
  • Jinja2 ==3.1.4
  • Markdown ==3.7
  • MarkupSafe ==3.0.2
  • PyJWT ==2.10.1
  • PyPika ==0.48.9
  • PySocks ==1.7.1
  • PyYAML ==6.0.2
  • Pygments ==2.19.1
  • RapidFuzz ==3.12.1
  • Rtree ==1.3.0
  • SQLAlchemy ==2.0.38
  • Werkzeug ==3.1.3
  • XlsxWriter ==3.2.2
  • absl-py ==2.1.0
  • accelerate ==1.2.1
  • aiofiles ==24.1.0
  • aiohappyeyeballs ==2.4.4
  • aiohttp ==3.11.11
  • aiohttp-cors ==0.7.0
  • aiosignal ==1.3.2
  • airportsdata ==20241001
  • annotated-types ==0.7.0
  • anyio ==4.8.0
  • appdirs ==1.4.4
  • asgiref ==3.8.1
  • astor ==0.8.1
  • asttokens ==3.0.0
  • async-timeout ==5.0.1
  • attrs ==24.3.0
  • automated-interpretability ==0.0.6
  • babe ==0.0.7
  • backoff ==2.2.1
  • bcrypt ==4.2.1
  • beartype ==0.14.1
  • beautifulsoup4 ==4.13.3
  • better-abc ==0.0.3
  • bidict ==0.23.1
  • bitsandbytes ==0.45.3
  • blake3 ==1.0.2
  • blinker ==1.9.0
  • blobfile ==3.0.0
  • boostedblob ==0.15.6
  • build ==1.2.2.post1
  • cachetools ==5.5.1
  • certifi ==2024.12.14
  • cffi ==1.17.1
  • chardet ==5.2.0
  • charset-normalizer ==3.4.0
  • chroma-hnswlib ==0.7.6
  • chromadb ==0.6.3
  • click ==8.1.8
  • cloudpickle ==3.1.1
  • coloredlogs ==15.0.1
  • colorful ==0.5.6
  • comm ==0.2.2
  • compressed-tensors ==0.8.1
  • config2py ==0.1.36
  • contourpy ==1.3.1
  • cryptography ==44.0.1
  • ctransformers ==0.2.27
  • cut-cross-entropy ==25.1.1
  • cycler ==0.12.1
  • dataclasses-json ==0.6.7
  • datasets ==2.21.0
  • debugpy ==1.8.12
  • decorator ==5.2.1
  • depyf ==0.18.0
  • diffusers ==0.32.2
  • dill ==0.3.8
  • diskcache ==5.6.3
  • distlib ==0.3.9
  • distro ==1.9.0
  • docker-pycreds ==0.4.0
  • docling ==2.25.1
  • docling-core ==2.21.1
  • docling-ibm-models ==3.4.1
  • docling-parse ==3.4.0
  • docstring_parser ==0.16
  • dol ==0.3.9
  • durationpy ==0.9
  • easyocr ==1.7.2
  • eindex-callum ==0.1.2
  • einops ==0.7.0
  • emoji ==2.14.1
  • et_xmlfile ==2.0.0
  • eval_type_backport ==0.2.2
  • evaluate ==0.4.3
  • exceptiongroup ==1.2.2
  • executing ==2.2.0
  • fancy-einsum ==0.0.3
  • fastapi ==0.115.6
  • fastchat ==0.1.0
  • fastjsonschema ==2.21.1
  • ffmpy ==0.5.0
  • filelock ==3.17.0
  • filetype ==1.2.0
  • fire ==0.7.0
  • flash_attn ==2.7.4.post1
  • flatbuffers ==25.2.10
  • fonttools ==4.56.0
  • frozenlist ==1.5.0
  • fsspec ==2024.6.1
  • gdown ==5.2.0
  • gguf ==0.10.0
  • gitdb ==4.0.12
  • google-api-core ==2.24.0
  • google-auth ==2.37.0
  • googleapis-common-protos ==1.66.0
  • gprof2dot ==2024.6.6
  • gradio ==5.16.1
  • gradio_client ==1.7.0
  • graze ==0.1.29
  • greenlet ==3.1.1
  • grpcio ==1.69.0
  • h11 ==0.14.0
  • hf_transfer ==0.1.9
  • html5lib ==1.1
  • httpcore ==1.0.7
  • httptools ==0.6.4
  • httpx ==0.27.2
  • httpx-sse ==0.4.0
  • huggingface-hub ==0.29.1
  • humanfriendly ==10.0
  • i2 ==0.1.46
  • idna ==3.10
  • imageio ==2.37.0
  • importlib-metadata ==5.2.0
  • importlib_resources ==6.5.2
  • iniconfig ==2.0.0
  • interegular ==0.3.3
  • ipykernel ==6.29.5
  • ipython ==8.32.0
  • ipywidgets ==8.1.5
  • itsdangerous ==2.2.0
  • jaxtyping ==0.2.36
  • jedi ==0.19.2
  • jiter ==0.8.2
  • joblib ==1.4.2
  • jsonlines ==3.1.0
  • jsonpatch ==1.33
  • jsonpointer ==3.0.0
  • jsonref ==1.1.0
  • jsonschema ==4.23.0
  • jsonschema-specifications ==2024.10.1
  • jupyter_client ==8.6.3
  • jupyter_core ==5.7.2
  • jupyterlab_widgets ==3.0.13
  • kiwisolver ==1.4.8
  • kubernetes ==32.0.0
  • langchain ==0.3.20
  • langchain-chroma ==0.2.2
  • langchain-community ==0.3.17
  • langchain-core ==0.3.41
  • langchain-docling ==0.2.0
  • langchain-nomic ==0.1.4
  • langchain-ollama ==0.2.3
  • langchain-text-splitters ==0.3.6
  • langdetect ==1.0.9
  • langsmith ==0.3.8
  • lark ==1.2.2
  • latex2mathml ==3.77.0
  • lazy_loader ==0.4
  • lingua ==4.15.0
  • lingua-language-detector ==2.0.2
  • linkify-it-py ==2.0.3
  • litellm ==1.59.0
  • llvmlite ==0.44.0
  • lm-format-enforcer ==0.10.9
  • loguru ==0.7.3
  • lxml ==5.3.1
  • markdown-it-py ==3.0.0
  • marko ==2.1.2
  • marshmallow ==3.26.1
  • matplotlib ==3.10.1
  • matplotlib-inline ==0.1.7
  • mdit-py-plugins ==0.4.2
  • mdurl ==0.1.2
  • memray ==1.15.0
  • mistral_common ==1.5.1
  • mmh3 ==5.1.0
  • monotonic ==1.6
  • mpire ==2.10.2
  • mpmath ==1.3.0
  • msgpack ==1.1.0
  • msgspec ==0.19.0
  • multidict ==6.1.0
  • multiprocess ==0.70.16
  • mypy-extensions ==1.0.0
  • natsort ==8.4.0
  • nbformat ==5.10.4
  • nest-asyncio ==1.6.0
  • networkx ==3.4.2
  • ninja ==1.11.1.3
  • nltk ==3.9.1
  • nnsight ==0.3.7
  • nomic ==3.4.1
  • numba ==0.61.0
  • numpy ==1.26.4
  • nvidia-cublas-cu12 ==12.4.5.8
  • nvidia-cuda-cupti-cu12 ==12.4.127
  • nvidia-cuda-nvrtc-cu12 ==12.4.127
  • nvidia-cuda-runtime-cu12 ==12.4.127
  • nvidia-cudnn-cu12 ==9.1.0.70
  • nvidia-cufft-cu12 ==11.2.1.3
  • nvidia-curand-cu12 ==10.3.5.147
  • nvidia-cusolver-cu12 ==11.6.1.9
  • nvidia-cusparse-cu12 ==12.3.1.170
  • nvidia-ml-py ==12.560.30
  • nvidia-nccl-cu12 ==2.21.5
  • nvidia-nvjitlink-cu12 ==12.4.127
  • nvidia-nvtx-cu12 ==12.4.127
  • oauthlib ==3.2.2
  • olefile ==0.47
  • ollama ==0.4.7
  • onnxruntime ==1.20.1
  • openai ==1.59.8
  • opencensus ==0.11.4
  • opencensus-context ==0.1.3
  • opencv-python-headless ==4.11.0.86
  • openpyxl ==3.1.5
  • opentelemetry-api ==1.30.0
  • opentelemetry-exporter-otlp-proto-common ==1.30.0
  • opentelemetry-exporter-otlp-proto-grpc ==1.30.0
  • opentelemetry-instrumentation ==0.51b0
  • opentelemetry-instrumentation-asgi ==0.51b0
  • opentelemetry-instrumentation-fastapi ==0.51b0
  • opentelemetry-proto ==1.30.0
  • opentelemetry-sdk ==1.30.0
  • opentelemetry-semantic-conventions ==0.51b0
  • opentelemetry-util-http ==0.51b0
  • orjson ==3.10.15
  • outlines ==0.1.11
  • outlines_core ==0.1.26
  • overrides ==7.7.0
  • packaging ==24.2
  • pandarallel ==1.6.5
  • pandas ==2.2.3
  • parallel-pandas ==0.6.5
  • parso ==0.8.4
  • partial-json-parser ==0.2.1.1.post5
  • patsy ==1.0.1
  • peft ==0.14.0
  • pexpect ==4.9.0
  • pillow ==10.4.0
  • plotly ==5.24.1
  • plotly-express ==0.4.1
  • pluggy ==1.5.0
  • polib ==1.2.0
  • posthog ==3.14.1
  • prometheus-fastapi-instrumentator ==7.0.2
  • prometheus_client ==0.21.1
  • prompt_toolkit ==3.0.50
  • propcache ==0.2.1
  • proto-plus ==1.25.0
  • protobuf ==5.29.3
  • psutil ==7.0.0
  • ptyprocess ==0.7.0
  • pure_eval ==0.2.3
  • py-cpuinfo ==9.0.0
  • py-spy ==0.4.0
  • py2store ==0.1.20
  • pyarrow ==18.1.0
  • pyasn1 ==0.6.1
  • pyasn1_modules ==0.4.1
  • pybind11 ==2.13.6
  • pyclipper ==1.3.0.post6
  • pycountry ==24.6.1
  • pycparser ==2.22
  • pycryptodomex ==3.21.0
  • pydantic ==2.10.5
  • pydantic-settings ==2.7.1
  • pydantic_core ==2.27.2
  • pydub ==0.25.1
  • pynndescent ==0.5.13
  • pyparsing ==3.2.0
  • pypdf ==5.3.0
  • pypdfium2 ==4.30.1
  • pyproject_hooks ==1.2.0
  • pytest ==8.3.4
  • pytest-profiling ==1.8.1
  • python-bidi ==0.6.6
  • python-dateutil ==2.9.0.post0
  • python-docx ==1.1.2
  • python-dotenv ==1.0.1
  • python-engineio ==4.11.2
  • python-iso639 ==2025.2.18
  • python-magic ==0.4.27
  • python-multipart ==0.0.20
  • python-oxmsg ==0.0.2
  • python-pptx ==1.0.2
  • python-socketio ==5.12.1
  • pytz ==2024.2
  • pyzmq ==26.2.1
  • ray ==2.40.0
  • referencing ==0.36.1
  • regex ==2024.11.6
  • requests ==2.32.3
  • requests-oauthlib ==2.0.0
  • requests-toolbelt ==1.0.0
  • rich ==13.9.4
  • rouge-score ==0.1.2
  • routellm ==0.2.0
  • rpds-py ==0.22.3
  • rsa ==4.9
  • ruff ==0.9.6
  • sae-lens ==5.4.1
  • safehttpx ==0.1.6
  • safetensors ==0.4.5
  • schedulefree ==1.4
  • scikit-image ==0.25.2
  • scikit-learn ==1.6.0
  • scipy ==1.15.1
  • seaborn ==0.13.2
  • semantic-version ==2.10.0
  • semchunk ==2.2.2
  • sentence-transformers ==3.4.1
  • sentencepiece ==0.2.0
  • sentry-sdk ==2.20.0
  • setproctitle ==1.3.4
  • sglang ==0.4.1.post6
  • shapely ==2.0.7
  • shellingham ==1.5.4
  • shortuuid ==1.0.13
  • shtab ==1.7.1
  • simple-parsing ==0.1.7
  • simple-websocket ==1.1.0
  • six ==1.17.0
  • smart-open ==7.1.0
  • smmap ==5.0.2
  • sniffio ==1.3.1
  • soupsieve ==2.6
  • stack-data ==0.6.3
  • starlette ==0.41.3
  • statsmodels ==0.14.4
  • steering-vectors ==0.10.2
  • sympy ==1.13.1
  • tabulate ==0.9.0
  • tenacity ==9.0.0
  • termcolor ==2.5.0
  • textual ==0.78.0
  • threadpoolctl ==3.5.0
  • tifffile ==2025.2.18
  • tiktoken ==0.7.0
  • tokenizers ==0.21.0
  • toml ==0.10.2
  • tomli ==2.2.1
  • tomlkit ==0.13.2
  • toolz ==1.0.0
  • torch ==2.5.1
  • torchvision ==0.20.1
  • tornado ==6.4.2
  • tqdm ==4.67.1
  • traitlets ==5.14.3
  • transformer-lens ==1.19.0
  • transformers ==4.49.0
  • triton ==3.1.0
  • trl ==0.9.4
  • typeguard ==4.4.1
  • typer ==0.12.5
  • typing-inspect ==0.9.0
  • typing_extensions ==4.12.2
  • tyro ==0.9.10
  • tzdata ==2024.2
  • uc-micro-py ==1.0.3
  • umap-learn ==0.5.7
  • unsloth_zoo ==2025.1.3
  • unstructured ==0.16.21
  • unstructured-client ==0.30.1
  • urllib3 ==2.3.0
  • uvicorn ==0.34.0
  • uvloop ==0.21.0
  • virtualenv ==20.29.2
  • vllm ==0.6.6.post1
  • wandb ==0.19.4
  • watchfiles ==1.0.4
  • wcwidth ==0.2.13
  • webencodings ==0.5.1
  • websocket-client ==1.8.0
  • websockets ==14.2
  • widgetsnbextension ==4.0.13
  • wordcloud ==1.9.4
  • wrapt ==1.17.2
  • wsproto ==1.2.0
  • xformers ==0.0.28.post3
  • xgboost ==2.1.4
  • xgrammar ==0.1.10
  • xxhash ==3.5.0
  • yarl ==1.18.3
  • zipp ==3.21.0
  • zstandard ==0.23.0