James Tsang

James Tsang

A developer.
github
twitter
tg_channel

ARTS 打卡第 4 天

今天打卡晚了二十幾分鐘。因為加班加上和老弟聊天聊得比較久,然後選讀了一篇關於用 LLM 進行 TDD 開發的文章,內容太長了,為了實現當天打卡又換了一篇,沒想到還是超時了,而且還換了一篇質量不夠高的文章,得不償失。不管怎樣,先用這篇文章完成打卡,用 LLM 進行 TDD 的文章作為緊接著的打卡文章的內容好了。

A:263. 丑数#

丑数 就是只包含质因数 2、3 和 5 的正整数。
给你一个整数 n ,请你判断 n 是否为 丑数 。如果是,返回 true ;否则,返回 false 。
示例 1:
输入:n = 6
输出:true
解释:6 = 2 × 3
示例 2:
输入:n = 1
输出:true
解释:1 没有质因数,因此它的全部质因数是 {2, 3, 5} 的空集。习惯上将其视作第一个丑数。
示例 3:
输入:n = 14
输出:false
解释:14 不是丑数,因为它包含了另外一个质因数 7 。

也是一道比較簡單的題目,沒有想到什麼理論化的方法,一開始忽略了 0 不是丑数,改了下後就提交了:

function isUgly(n: number): boolean {
  if (n === 0) {
    return false
  }
  if (n === 1) {
    return true
  }
  if (n % 2 === 0) {
    return isUgly(n / 2)
  }
  if (n % 3 === 0) {
    return isUgly(n / 3)
  }
  if (n % 5 === 0) {
    return isUgly(n / 5)
  }
  return false
}

提交結果為:

1013/1013 cases passed (56 ms)
Your runtime beats 100 % of typescript submissions
Your memory usage beats 38.09 % of typescript submissions (44 MB)

值得注意的是我這裡是用遞歸實現的,換成 while (true) 的循環也是可以的。

R:LangChain + Streamlit + Llama: Bringing Conversational AI to Your Local Machine#

由於大家對大語言模型還有 LangChain 應該都很熟悉了,這裡我只再簡單描述一下。

大語言模型引起了巨大的關注,許多開發者也在用大語言模型做聊天機器人、個人助手或內容創造,大語言模型的可能性讓開發者、AI、NLP 的社區裡都湧現出了巨大的熱情。

可以向大語言模型注入領域特定的數據來高效地解決查詢問題,尤其在公司內部的文檔知識庫方面有用武之地。用於實現這種目的的架構叫作 “檢索增強生成” 或者 “生成式問答”。

LangChain 是什麼?LangChain 一個將大語言 AI 應用的組成部分方便地串聯在一起的研發框架,可以方便開發者快速實現聊天機器人等應用。

這篇文章主要講怎麼用 LangChain 和 LLaMA 7B 模型創建一個文檔助手 (個人感覺有點過時了,現在已經是 LLaMA2 了)

文章信息結構:

  1. 創建虛擬環境和文件結構
  2. 在本地拉取大語言模型
  3. 集成大語言模型到 LangChain 中並自定義 Prompt 模板
  4. 文檔檢索和回答生成
  5. 使用 Streamlit 創建應用

1. 創建虛擬環境和文件結構#

創建基本的文件結構和 Python 虛擬環境,主要是模型文件、Notebook 文件、app.py 應用程序入口文件,可以 clone 作者的倉庫:DocQA

2. 在本地拉取大語言模型#

LLaMA 是 Meta 發布的大語言模型,LLaMA2 可以免費商用,這篇文章用的是 LLaMA1。去 HuggingFace 找到 LLaMA 模型下載 bin 文件到 models 目錄內即可。

GGML 是一個開源的 C++ 寫的機器學習張量庫,可以通過量化的方式在我們的消費級硬件上運行 LLM。

那什麼是量化呢?LLM 的權重是浮點型的數值,相比於整型數值更佔用空間和算力。量化就是減少權重的精度來減少資源佔用。GGML 支持 4-bit、5-bit 和 8-bit 的量化。

需要權衡考慮內存、硬盤以及模型效果來選擇模型參數大小和量化方式。大小越大、量化精度越高效果越好,資源佔用也越多。

如果 GGML 是 C++ 庫,怎麼在 Python 裡面用起來呢?這就需要用到 llma-cpp-python 項目了,這是一個 llama.cpp 的 Python binding,可以讓我們用 Python 去運行 LLaMA 模型。

介紹了這麼多,其實運行起來非常簡單,幾行 Python 代碼就搞定了:

image

3. 集成大語言模型到 LangChain 中並自定義 Prompt 模板#

對 LLM 來說,簡化理解它的運行就是輸入文本、輸出文本,因此對 LangChain 來說大部分工作也是以文本為中心的。

Prompt 的細微差別就會對 LLM 的運行效果產生巨大的差距,因此專門產生了 Prompt Engineering 的概念,來考慮怎麼生成質量更好的 Prompt。為了無縫於 LLM 交互,LangChain 提供了 Prompt 模板開發的功能,它通常包含兩部分:文本模板以及動態參數:

簡單的應用把 Prompt 和輸入參數傳給 LLM 生成結果就好了,但複雜的應用一般需要串接 LLM 以及其它組件。LangChain 提供了串接的開發方式,可以串行調用一系列組件。

4. 文檔檢索和回答生成#

在大量 LLM 應用中,用戶需要的數據都不在模型的訓練數據集中,需要外挂到 Prompt 裡。LangChain 提供了加載、轉換、存儲和查詢這些數據的必要組件:

image

這五個過程是:文檔加載 - 文檔轉換 - Embedding - 向量存儲 - 向量檢索,以下是文章檢索的全流程:

image

這個過程比較長就不在這裡展開了,值得注意的是因為這是一個本地部署的方案,因此 embedding 模型也不是用的遠程服務,而是用 LlamaCppEmbeddings 這個 LangChain 組件來用 LLaMA 模型做 Embedding。

5. 使用 Streamlit 創建應用#

作者沒有詳細展開 Streamlit,因為這對主鏈路來說是一個相對可選的步驟。不過使用 Streamlit 實現文件上傳的時候作者強調為了防止內存不夠用,他是在一個臨時目錄內保存上傳的文件為 raw.txt 的,當前只支持 txt 類型文件,也可以改造成支持 PDF、CSV 的文件。最後通過調用 Streamlit 庫,就把這個基於 LangChain 的 LLM 應用變成了一個網頁應用:

# Bring in deps
import streamlit as st 
from langchain.llms import LlamaCpp
from langchain.embeddings import LlamaCppEmbeddings
from langchain.prompts import PromptTemplate
from langchain.chains import LLMChain
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma


# Customize the layout
st.set_page_config(page_title="DOCAI", page_icon="🤖", layout="wide", )     
st.markdown(f"""
            <style>
            .stApp {{background-image: url("https://images.unsplash.com/photo-1509537257950-20f875b03669?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1469&q=80"); 
                     background-attachment: fixed;
                     background-size: cover}}
         </style>
         """, unsafe_allow_html=True)

# function for writing uploaded file in temp
def write_text_file(content, file_path):
    try:
        with open(file_path, 'w') as file:
            file.write(content)
        return True
    except Exception as e:
        print(f"Error occurred while writing the file: {e}")
        return False

# set prompt template
prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.
{context}
Question: {question}
Answer:"""
prompt = PromptTemplate(template=prompt_template, input_variables=["context", "question"])

# initialize hte LLM & Embeddings
llm = LlamaCpp(model_path="./models/llama-7b.ggmlv3.q4_0.bin")
embeddings = LlamaCppEmbeddings(model_path="models/llama-7b.ggmlv3.q4_0.bin")
llm_chain = LLMChain(llm=llm, prompt=prompt)

st.title("📄 Document Conversation 🤖")
uploaded_file = st.file_uploader("Upload an article", type="txt")

if uploaded_file is not None:
    content = uploaded_file.read().decode('utf-8')
    # st.write(content)
    file_path = "temp/file.txt"
    write_text_file(content, file_path)   
    
    loader = TextLoader(file_path)
    docs = loader.load()    
    text_splitter = CharacterTextSplitter(chunk_size=100, chunk_overlap=0)
    texts = text_splitter.split_documents(docs)
    db = Chroma.from_documents(texts, embeddings)    
    st.success("File Loaded Successfully!!")
    
    # Query through LLM    
    question = st.text_input("Ask something from the file", placeholder="Find something similar to: ....this.... in the text?", disabled=not uploaded_file,)    
    if question:
        similar_doc = db.similarity_search(question, k=1)
        context = similar_doc[0].page_content
        query_llm = LLMChain(llm=llm, prompt=prompt)
        response = query_llm.run({"context": context, "question": question})        
        st.write(response)

image

我個人比較關注 Streamlit 的應用,感覺繼 Gradio 實現原型開發後,更複雜的應用開發很有可能是 Streamlit 的機會,可惜這篇文章沒有深入展開,我最想看的內容草草略過了。

T:CoDeF#

一個視頻轉視頻的 LLM,輸出穩定,質量也不錯。

image

S:SQ3R 閱讀法#

SQ3R 代表著五個單詞:Survey(瀏覽),Question(提問),Read(閱讀),Recite(復述),Review(複習) 在學習之前,先把內容大概瀏覽一遍,然後在這個瀏覽的基礎上提出自己的問題,這是講什麼的,解決什麼問題。 然後帶著這個問題去深入閱讀。通過閱讀找出答案。
最後關上書,自己復述一遍,這個書是講什麼的,然後我們先有什麼問題,這個書是怎麼解決。 最後是進行複習,鞏固學習成果。 這五步下來,這個書的內容就能夠被真正的吸收。


Reference:

  1. ARTS 打卡活動
載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。