2025/1/16

Xorg, VirtualGL and VNC

ref: 在headless server 上,要用 remote desktop 又要使用到 GPU 的話,就要用到這三個。
  • VirtualGL : 把 application 的 OpenGL 呼叫轉送到另一個xserver,並且把這個 xserver render 的結果拿來,交給真正負責application 顯示的 x server
  • Xorg : 負責一個GPU加速功能的 X server
  • TurboVNC : 負責顯示
所以要用 Xorg create 一個使用 GPU (Nvidia) 的 X config.
然後啟動一個 X server

然後啟動 TurboVNC server,這個server 會把畫面畫出來,並且傳給 vncviewer

然後用 vglrun 來啟動 application.


以 CARLA 為例,要在 headless server 上 remote run.

先 create 一個 nvidia 的 Xserver:
$ nvidia-xconfig --query-gpu-info
Number of GPUs: 1

GPU #0:
  Name      : NVIDIA TITAN RTX
  UUID      : GPU-XXXXXXXXXXXX
  PCI BusID : PCI:1:0:0

  Number of Display Devices: 1

  Display Device 0 (TV-6):
      No EDID information available.
看一下 GPU 的 PCI Bus Id.
然後 create 一個 xorg.conf:
$ sudo nvidia-xconfig -a --allow-empty-initial-configuration --use-display-device=None --virtual=1920x1080 --busid=PCI:1:0:0

Using X configuration file: "/etc/X11/xorg.conf".
Option "AllowEmptyInitialConfiguration" "True" added to Screen "Screen0".
Backed up file '/etc/X11/xorg.conf' as '/etc/X11/xorg.conf.backup'
New X configuration file written to '/etc/X11/xorg.conf'
然後因為 nvidia driver 版本大於 440.xx,所以在 xorg.conf 的 Screen 的地方加上:
Option "HardDPMS" "false"



啟動一個 Xserver session,為了讓一班 user 也能啟動 X session,要修改 /etc/X11/Xwrapper.conf,加入下面:
allowed_users=anybody
needs_root_rights=yes
然後 user 要在 tty group 裡。

啟動一個 X session,使用 display number 7

X.Org X Server 1.21.1.11
X Protocol Version 11, Revision 0
Current Operating System: Linux i7-14700 6.8.0-35-generic #35-Ubuntu SMP PREEMPT_DYNAMIC Mon May 20 15:51:52 UTC 2024 x86_64
Kernel command line: BOOT_IMAGE=/boot/vmlinuz-6.8.0-35-generic root=UUID=e4ea2afe-cc4e-42ce-a53f-5032e417f9f7 ro
xorg-server 2:21.1.12-1ubuntu1.1 (For technical support please see http://www.ubuntu.com/support)
Current version of pixman: 0.42.2
        Before reporting problems, check http://wiki.x.org
        to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
        (++) from command line, (!!) notice, (II) informational,
        (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.7.log", Time: Fri Jan 17 05:52:20 2025
(==) Using config file: "/etc/X11/xorg.conf"
(==) Using system config directory "/usr/share/X11/xorg.conf.d"
The XKEYBOARD keymap compiler (xkbcomp) reports:
> Warning:          Could not resolve keysym XF86CameraAccessEnable
> Warning:          Could not resolve keysym XF86CameraAccessDisable
> Warning:          Could not resolve keysym XF86CameraAccessToggle
> Warning:          Could not resolve keysym XF86NextElement
> Warning:          Could not resolve keysym XF86PreviousElement
> Warning:          Could not resolve keysym XF86AutopilotEngageToggle
> Warning:          Could not resolve keysym XF86MarkWaypoint
> Warning:          Could not resolve keysym XF86Sos
> Warning:          Could not resolve keysym XF86NavChart
> Warning:          Could not resolve keysym XF86FishingChart
> Warning:          Could not resolve keysym XF86SingleRangeRadar
> Warning:          Could not resolve keysym XF86DualRangeRadar
> Warning:          Could not resolve keysym XF86RadarOverlay
> Warning:          Could not resolve keysym XF86TraditionalSonar
> Warning:          Could not resolve keysym XF86ClearvuSonar
> Warning:          Could not resolve keysym XF86SidevuSonar
> Warning:          Could not resolve keysym XF86NavInfo
Errors from xkbcomp are not fatal to the X server



啟動 Turbovnc 的 vnc server,負責 application 的 display,用 8 作為 display number:
$ /opt/TurboVNC/bin/vncserver :8

Desktop 'TurboVNC: i7-14700:8 (charles-chang)' started on display i7-14700:8

Starting applications specified in /opt/TurboVNC/bin/xstartup.turbovnc
Log file is /home/charles/.vnc/i7-14700:8.log
如果是第一次啟動,會要求給一個 vncviewer 用的 password.

vnc server 啟動之後,其他pc 就可以透過 viewer 來顯示 vncserver 的內容。
vncserver 的 service port 是 5900+display numner,
也就是說,剛剛的設定,service port 是 5908


之後就可以用 vglrun 來執行 application,讓執行程式使用 virtualgl 提供的 opengl 服務,並且經由 DISPLAY 變數傳送render 的結果:
~$ DISPLAY=:8 vglrun -d :7 glxgears
先指定DISPLAY環境變數是:8 (VNCSERVER),然後用 "-d :7" 指定 opengl rendering 交給 display :7 (nvidia X session) 負責。

2025/1/15

MESA-LOADER: failed to open iris

ref:
先是...
MESA-LOADER: failed to open iris: /usr/lib/dri/iris_dri.so: cannot open shared object file: 
No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
failed to load driver: iris
MESA-LOADER: failed to open swrast: /usr/lib/dri/swrast_dri.so: cannot open shared object file: 
No such file or directory (search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  149 (GLX)
  Minor opcode of failed request:  3 (X_GLXCreateContext)
  Value in failed request:  0x0
  Serial number of failed request:  167
  Current serial number in output stream:  168
所以參考上面的 ref,去看 /usr/lib 下果然沒有 dri 目錄。所以把安裝位置 ln 過來...
sudo apt --reinstall install libgl1-mesa-dri
cd /usr/lib
sudo ln -s x86_64-linux-gnu/dri ./dri
然後 Error:
MESA-LOADER: failed to open iris: /home/charles/miniconda3/envs/carla/bin/../lib/libstdc++.so.6: 
version `GLIBCXX_3.4.30' not found (required by /lib/x86_64-linux-gnu/libLLVM-17.so.1) 
(search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
failed to load driver: iris
MESA-LOADER: failed to open swrast: /home/charles/miniconda3/envs/carla/bin/../lib/libstdc++.so.6: 
version `GLIBCXX_3.4.30' not found (required by /lib/x86_64-linux-gnu/libLLVM-17.so.1) 
(search paths /usr/lib/x86_64-linux-gnu/dri:\$${ORIGIN}/dri:/usr/lib/dri, suffix _dri)
X Error of failed request:  BadValue (integer parameter out of range for operation)
所以看一下 conda 系統的 libstdc++.so.6 的 GLIBCXX 支援版本有:
$ strings /home/charles/miniconda3/lib/libstdc++.so.6 | grep ^GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
...
GLIBCXX_3.4.28
GLIBCXX_3.4.29
GLIBCXX_DEBUG_MESSAGE_LENGTH
GLIBCXX_3.4.21
GLIBCXX_3.4.9
GLIBCXX_3.4.10
GLIBCXX_3.4.16
GLIBCXX_3.4.1
...
GLIBCXX_3.4.4
GLIBCXX_3.4.26
果然沒有 3.4.30

因為是 libstdc++.so.6.0.29
系統的 /usr/lib/x86-linux-gnu/libstdc++.so 是 6.0.33

所以把 /usr/lib/x86_64-linux-gnu/ 的 6.0.33 copy 到 env 的 lib,然後重新 ln libstdc++.so.6 到 libstdc++.so.6.0.33 就可以了。

md file, markdown reader in linux console

bat

有在 ubuntu 的 apt repo 里,所以用 apt install bat 就可以。
但是command 是 batcat,
他是希望跟 cat 一樣的用法。

install 完後,因為它支援 theme,所以default theme不喜歡的話,就要產生一個 config,然後改 default theme.
$ batcat --generate-config-file
Success! Config file written to /home/charles/.config/bat/config
然後去修改 ~/.config/bat/config
-- #--theme="TwoDark"
++ --theme="GitHub"
default theme 是給 darkmode用的。bright mode 可以用 "GitHub" 這個 theme.

使用方法就跟 cat 一樣:
batcat README.md



batcat 不太好用,markdown 語法沒有render的很好,有些還是 raw output,
所以用 mdcat 試試看。
是用 rust 寫的,apt 還沒有。
所以要clone 下來 build

跟 batcat 比起來是 render 多一點 markdown 語法了。



update : 最後還是去裝 chrome 的 extension : markdown viewer

2025/1/14

Carla : Install and run on Linux

網站說明有latest, stable, 0.9.15 ...etc,但是github 的 Download 只有 0.9.15,所以猜 latest 也是 0.9.15 (?)
github Download page 還有 nightly build,說明包含 bugfix 和 new feature,所以猜是 unstable.

Download CARLA_0.9.15.tar.gz,解開會有多目錄,所以在一個目錄中解開比較好。

從 Quick start package installation : Install Client Library
使用 tar.gz 檔安裝,PythonAPI/carla/dist 中有需要的 python packages file : *.whl
提供的 python version 是 : cp37,所以 carla-0.9.15 的 python 版本應該是 python3.7

這個folder 提供的對應 whl 檔,跟用 pip install carla 安裝的檔案相同。
使用的是 carla-0.9.15-cp37-cp37m-manylinux_2_27_x86_64.whl

除此之外,還要install pygame 和 numpy 兩個 package,就可以開始 run :
文件說明是
./CarlaUE4.sh
結果發現沒有使用 GPU,參考cannot run Carla using nvidia GPU under Linux with multi-GPU installed : PRIME instruction ignored by Carla #4716
加上 option
./CarlaUE4.sh -prefernvidia
就可以了。


從主網站 carla.org 進入可以看到release 0.10.0的說明。
0.10.0 的 python 版本不同了。

一樣從whl的檔名來看,0.10.0 的 python 版本應該是 3.10
一樣解開download 的 0.10.0 (這次是zip檔),到 PythonAPI/carla 安裝 requirement.txt,再裝 dist/*.whl,之後就可以啟動:
./CarlaUnreal.sh 
0.10.0 不用家 -prefernvidia,就會用 GPU了。

0.10.0 vRAM用到 8G以上,使用 RTX4070,移動鏡頭快一點就會出現 vulkan out of memory Error.



carla script 啟動的是 server,控制的化,可以參考 Python_API/Example 下的 python code.
在server running 的情況下, run 這些 python code 就可以調整carla 的內容。

在啟動 automatic_control.py 時出現 mesa load iris error.依照這一篇 解決。


2024/11/24

Simple URL RAG with ollama locally

這篇就是翻譯下面這個 link,source code 也是下面這個 link 的 code: 文章中,embedding 用了 openai,為了作到完全 local,改用 OllamaEmbeddings

url rag 做的大概是..
列出url,把所有 url 讀進來,把內容攤平成一維
import os
os.environ['USER_AGENT'] = 'myagent'

from langchain_community.document_loaders import WebBaseLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
# List of URLs to load documents from
urls = [
    "https://lilianweng.github.io/posts/2023-06-23-agent/",
    "https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/",
    "https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/",
]
# Load documents from the URLs
docs = [WebBaseLoader(url).load() for url in urls]
docs_list = [item for sublist in docs for item in sublist]
再把網頁內容分成一小段一小段
# Initialize a text splitter with specified chunk size and overlap
text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(
    chunk_size=250, chunk_overlap=0
)
# Split the documents into chunks
doc_splits = text_splitter.split_documents(docs_list)
把這些一小段一小段的句子,轉成 embedding,也就是一個 N 維 tensor。
因為要 run locally,所以用 OllamaEmbeddings 來做:
from langchain_ollama import OllamaEmbeddings

embeddings = OllamaEmbeddings(
    model="llama3",
)
所有字句轉成 embedding/tensor 後,要放到一個 local 的 database 里,讓𠹌一下 user 問問題的時候,來databasae 找答案。
這邊用 SKLearnVectorStore 這個 database :
from langchain_community.vectorstores import SKLearnVectorStore
from langchain_openai import OpenAIEmbeddings
# Create embeddings for documents and store them in a vector store
vectorstore = SKLearnVectorStore.from_documents(
    documents=doc_splits,
    embedding=embeddings,
)
retriever = vectorstore.as_retriever(k=4)
RAG 的 vectorstore 和 sql 不同的地方是,在 query 時,vecrotstore 給的是最接近 query 的內容,而不是像 sql 一樣,要完全 match 的 data。

url 資料都準備好了,接下來就是 ollama 對接 LLM 的部份。
prompt template. TAG process chain.
from langchain_ollama import ChatOllama
from langchain.prompts import PromptTemplate
from langchain_core.output_parsers import StrOutputParser
# Define the prompt template for the LLM
prompt = PromptTemplate(
    template="""You are an assistant for question-answering tasks.
    Use the following documents to answer the question.
    If you don't know the answer, just say that you don't know.
    Use three sentences maximum and keep the answer concise:
    Question: {question}
    Documents: {documents}
    Answer:
    """,
    input_variables=["question", "documents"],
)

# Initialize the LLM with Llama 3.1 model
llm = ChatOllama(
    model="llama3.1",
    temperature=0,
)

rag_chain = prompt | llm | StrOutputParser()
做出 RAG class:
# Define the RAG application class
class RAGApplication:
    def __init__(self, retriever, rag_chain):
        self.retriever = retriever
        self.rag_chain = rag_chain
    def run(self, question):
        # Retrieve relevant documents
        documents = self.retriever.invoke(question)
        # Extract content from retrieved documents
        doc_texts = "\\n".join([doc.page_content for doc in documents])
        # Get the answer from the language model
        answer = self.rag_chain.invoke({"question": question, "documents": doc_texts})
        return answer
用這個 RAG class 來測試
# Initialize the RAG application
rag_application = RAGApplication(retriever, rag_chain)
# Example usage
question = "What is prompt engineering"
answer = rag_application.run(question)
print("Question:", question)
print("Answer:", answer)
輸出會是..
Question: What is prompt engineering
Answer: Prompt engineering is the process of designing and optimizing input prompts for language models, such as chatbots or virtual
assistants. According to Lilian Weng's 2023 article "Prompt Engineering", this involves techniques like word transformation, character 
transformation, and prompt-level obfuscations to improve model performance. The goal is to create effective and efficient prompts that 
elicit accurate responses from the model.


其他的 ref,用 web UI

2024/11/20

AI toolkit for VSCode: config to use ollama

這個雖然現在好像還沒有什麼功能,但是好像是唯一不用付錢的 ai assistant.
最新的更新支援 local ollama 了,所以來試試看。

原來 這個 extension 的說明文件都在github : doc: overview
要使用 ollama 的話,首先當然要 setup 好自己的 ollama service (ref:ollama run llama locally)
記得要對 local ip 開放。

ai toolkit 設定部分,在安裝完後,VS Code 左邊 panel 會多一個 item,ai toolkit item,
最上面,My Models 右邊的 "+" 按下去,會出現 Add remote model (1/4),意思是有四個步驟,現在做第一步。
第一步是設定 ollama url,我的就是
http://192.168.145.64:11434/v1/chat/completions
Enter 後,第二步,要 load 的 model name。
這部分,到 ollama sever 上,用 ollama list 列出,挑出要load 的 model name,要全名。
qwen2.5-coder:14b
Enter 後第三步是名子,給這格 model setup 的name,隨便。
最後一步是authetication key,ollama 不需要,所以 Enter w就可以。

2024/11/19

Try Web front end for whisper

先來試試 他是用Grandio 做 whisper 的 web front end
python 用 3.11,然後 clone source ans install requirements
git clone https://github.com/jhj0517/Whisper-WebUI.git
cd Whisper-WeUI
pip install -r requirements.txt
因為我用 conda ,所以把 start-webui.sh的 venc/bin/activate comment 掉。
然後用 public serv:
./start-webui.sh --server_name=0.0.0.0b --inbrowser=false
把影片拖到網頁,選 large-v2,輸出 srt,開始...
看 console output 是開始下載model...所以網頁的 progress bar 沒有動作。
model download 完,開始轉換....
結果出現 Error:
Unable to load any of {libcudnn_ops.so.9.1.0, libcudnn_ops.so.9.1, libcudnn_ops.so.9, libcudnn_ops.so}
參考 Downgrade ctranslate2:
pip install ctranslate2==4.4.0
之後,就沒 Error 了。

實際測試各個 model,發現並不是越大就越好。
在轉換長影片(2:30)時,越 1:00 後的文字出現問題,一直重復。