2.3.Step-by-Step Explanation
Step 1: Configure Remote Server Information
REMOTE_USER="ubuntu" # x86 server login username
REMOTE_IP="192.168.41.1" # x86 server IP
REMOTE_DIR="/home/ubuntu" # Working directory on x86
RELEASE_DIR="tkvoice_release_0.3.25_0324_101621" # Extract directory name
Purpose: Define connection parameters that will be used by all subsequent remote operations.
Customization: If your network configuration is different, modify these variables:
# Example: x86 user is 'lab', IP is 192.168.1.100
REMOTE_USER="lab"
REMOTE_IP="192.168.1.100"
REMOTE_DIR="/home/lab"
Step 2: Verify Installation Package Integrity
# Check if tar package exists
if [ ! -f "${RELEASE_DIR}.tar" ]; then
echo "[ERROR] Cannot find ${RELEASE_DIR}.tar"
exit 1
fi
# Check if necessary directories exist in tar package
if ! tar -tf "${RELEASE_DIR}.tar" | grep -q "${RELEASE_DIR}/res/docker_funasr/"; then
echo "[ERROR] ${RELEASE_DIR}/res/docker_funasr/ not found in tar package"
exit 1
fi
Purpose: Prevent subsequent errors.
Logic:
[ ! -f file ]- Check if file does not existtar -tf- List tar package contents (without extracting)grep -q- Silent search (returns only 0 or 1)
Troubleshooting:
# Check if tar package is corrupted
tar -tzf "${RELEASE_DIR}.tar" > /dev/null
# List directories in tar package
tar -tf "${RELEASE_DIR}.tar" | head -20
Step 3: Extract ASR-Related Files to Local
cd "${PARENT_DIR}"
tar -xvf "${RELEASE_DIR}.tar" \
"${RELEASE_DIR}/uninstall.sh" \
"${RELEASE_DIR}/res/docker_funasr/"
Purpose: Extract only ASR-related files (saves time and space), not the entire package.
Parameter Explanation:
-x: Extract-v: Verbose, show detailed information-f: Specify file- Last parameters specify paths to extract (multiple can be specified)
Result:
Current Directory/
└── tkvoice_release_0.3.25_0324_101621/
├── uninstall.sh
├── res/
│ └── docker_funasr/
│ ├── install_asr.sh
│ ├── startup.sh
│ ├── uninstall_asr.sh
│ └── ... (other Docker-related files)
└── ... (other files not yet extracted)
Step 4: Transfer docker_funasr to x86 Server
rsync -av --progress --delete -e "ssh -o StrictHostKeyChecking=no" \
res/docker_funasr \
${REMOTE_USER}@${REMOTE_IP}:${REMOTE_DIR}/
Purpose: Securely transfer ASR Docker files to x86 via SSH.
rsync Parameter Details:
| Parameter | Action | Description |
|---|---|---|
-a | archive mode | Preserves permissions, timestamps, symlinks |
-v | verbose | Shows detailed information |
--progress | show progress | Display transfer percentage for each file |
--delete | delete extra files | Fully synchronize remote directory with local |
-e ssh | use SSH | Instead of default rsh |
StrictHostKeyChecking=no | skip key confirmation | No need to manually enter yes |
Transfer Process Example:
sending incremental file list
res/docker_funasr/
res/docker_funasr/install_asr.sh
1.2K 100% 1.15MB/s 0:00:00 (xfer#1, to-check=5/7)
res/docker_funasr/startup.sh
2.5K 100% 2.43MB/s 0:00:00 (xfer#2, to-check=4/7)
...
sent 2,500 bytes received 35 bytes 5,070 bytes/sec
total size is 50,000 speedup is 19.92
If Transfer Fails:
# Test SSH connection
ssh -i ~/.ssh/id_rsa ubuntu@192.168.41.1 "echo 'SSH connection successful'"
# Check target directory permissions
ssh ubuntu@192.168.41.1 "ls -la /home/ubuntu/"
# Manual transfer (if rsync unavailable)
scp -r res/docker_funasr ubuntu@192.168.41.1:/home/ubuntu/
Step 5: Execute ASR Installation Script on x86
ssh -t ${REMOTE_USER}@${REMOTE_IP} \
"cd ${REMOTE_DIR}/docker_funasr && bash install_asr.sh"
Purpose: Remotely execute ASR Docker installation on x86 server.
Parameter Explanation:
-t: Allocate pseudo-terminal (interactive SSH)- Commands in quotes are executed on remote server
What install_asr.sh Does:
The install_asr.sh on x86 will:
- Install Docker (if not installed)
- Load or pull Funasr Docker image
- Start Funasr container, listening on 192.168.41.1:10097
Monitor Remote Execution:
To see detailed output of remote execution, modify to:
ssh ${REMOTE_USER}@${REMOTE_IP} \
"cd ${REMOTE_DIR}/docker_funasr && bash -x install_asr.sh"
# -x parameter will print each executed command
Step 6: Delete Local Temporary ASR Files
cd "${BASE_DIR}/res"
rm -rf docker_funasr
Purpose: Free up local disk space. ASR files have been synchronized to x86, no need to keep local copy.
Step 7: Install Python Dependencies
7.1 Extract Dependency Packages
tar -xvf "${RELEASE_DIR}.tar" \
"${RELEASE_DIR}/res/onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl" \
"${RELEASE_DIR}/res/onnxruntime_gpu-1.20.1-cp310-cp310-linux_aarch64.whl" \
"${RELEASE_DIR}/res/piper_tts-1.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl"
Purpose: Extract only required Python packages (wheel format).
Package Details:
| Package Name | Version | Purpose | Description |
|---|---|---|---|
| onnxruntime | 1.23.2 | CPU Inference | For Piper TTS and other ONNX models |
| onnxruntime_gpu | 1.20.1 | GPU Inference | Uses Orin GPU acceleration |
| piper_tts | 1.3.0 | TTS Synthesis | Text-to-speech library |
Filename Format Explanation:
piper_tts-1.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl
├─ 1.3.0 : Package version
├─ cp39 : CPython 3.9+
├─ abi3 : Stable ABI (backward compatible)
├─ aarch64 : ARM 64-bit architecture
└─ manylinux_2_x : Linux distribution compatibility
7.2 Uninstall Old Versions
python3 -m pip uninstall onnxruntime piper-tts onnxruntime-gpu -y || \
sudo python3 -m pip uninstall onnxruntime piper-tts onnxruntime-gpu -y || \
true
Purpose: Remove old versions to prevent version conflicts.
7.3 Install ONNX Runtime CPU and TTS
python3 -m pip install --no-cache-dir \
onnxruntime-1.23.2-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl \
piper_tts-1.3.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl \
websockets==15.0.1
Purpose: Install TTS and networking libraries.
Parameter Explanation:
--no-cache-dir: Don't save cache, saves disk space.whlfiles : Local wheel packages (pre-compiled)websockets: WebSocket library (for Funasr communication)
Version Selection Reasons:
websockets==15.0.1: Compatible with Funasr communication
7.4 Uninstall CPU Version ONNX Runtime
python3 -m pip uninstall onnxruntime -y || \
sudo python3 -m pip uninstall onnxruntime -y || \
true
Purpose: Remove CPU version to make room for GPU version.
7.5 Install GPU Version ONNX Runtime
python3 -m pip install --no-cache-dir \
onnxruntime_gpu-1.20.1-cp310-cp310-linux_aarch64.whl
Purpose: Install GPU-accelerated version for faster TTS inference.
Performance Comparison:
- CPU version: ~0.5 seconds to generate 1 second of speech
- GPU version: ~0.1 seconds to generate 1 second of speech (5x acceleration)
Why Install Separately:
CPU and GPU versions of onnxruntime conflict. Must install CPU version first (required by piper_tts), then replace with GPU version.
7.6 Clean Up Wheel Files
rm -f *.whl
Purpose: Delete installed wheel packages to free disk space (~500MB saved).
Step 8: Install Ollama
8.1 Extract Ollama Scripts
tar -xvf "${RELEASE_DIR}.tar" \
"${RELEASE_DIR}/res/ollama/uninstall_ollama.sh" \
"${RELEASE_DIR}/res/ollama/install_ollama.sh" \
"${RELEASE_DIR}/res/ollama/import_ollama_model.sh"
Purpose: Extract Ollama installation and uninstallation scripts.
8.2 Execute Ollama Installation
cd "${BASE_DIR}/res/ollama"
./install_ollama.sh "${PARENT_DIR}" "${RELEASE_DIR}"
Purpose: Run Ollama installation script.
Parameter Explanation:
${PARENT_DIR}: Working directory path${RELEASE_DIR}: Extract directory name
What install_ollama.sh Does:
- Detect if Ollama is already installed
- If not installed, download and install Ollama
- Start Ollama service
- Import qwen2.5:1.5b model
8.3 Clean Up Ollama Temporary Files
sudo find "${BASE_DIR}/res/ollama" \
-mindepth 1 \
! -name 'uninstall_ollama.sh' \
-exec rm -rf {} +
Purpose: Delete Ollama temporary files but keep uninstall script.
Parameter Explanation:
-mindepth 1: Don't delete the directory itself, only contents! -name: Exclude (don't delete) uninstall script-exec rm -rf {} +: Execute delete for each matched item
Result: Preserves uninstall script for future maintenance.
Step 9: Extract Main Project Files
tar -xvf "${RELEASE_DIR}.tar" \
"${RELEASE_DIR}/tkvoice.sh" \
"${RELEASE_DIR}/version.txt" \
"${RELEASE_DIR}/res/piper_voices/" \
"${RELEASE_DIR}/src/"
Purpose: Extract project source code, startup scripts, and TTS voice models.
Key Files:
| File/Directory | Purpose | Description |
|---|---|---|
tkvoice.sh | Startup Script | Used to manage service (start/stop/restart) |
version.txt | Version Info | Version tracking |
res/piper_voices/ | TTS Voice Model | Chinese voice (huayan-medium) |
src/ | Source Code | audio_message and audio_service packages |
Step 10: Compile ROS 2 Packages
cd "${BASE_DIR}"
echo "[INFO] Starting to compile ROS2 packages audio_message and audio_service..."
colcon build --packages-select audio_message audio_service
echo "[OK] ROS2 package compilation complete"
Purpose: Compile ROS 2 packages using colcon.
Compilation Process:
Starting >>> audio_message
Finished <<< audio_message [0.5s]
Starting >>> audio_service
[100%] Linking CXX executable ...
[100%] Built target ...
Finished <<< audio_service [5.2s]
Summary: 2 packages finished
Compilation Results:
${BASE_DIR}/
├── build/ # Intermediate build files
├── install/ # Installed packages (used by ROS environment)
├── log/ # Compilation logs
└── src/ # Source code
Common Compilation Errors:
| Error | Cause | Solution |
|---|---|---|
ament_cmake not found | ROS 2 environment not initialized | source /opt/ros/humble/setup.bash |
Permission denied | Insufficient user privileges | sudo chown -R $USER:$USER build install |
Package not found | Dependencies not installed | Check package.xml dependencies |
Step 11: Completion Message
echo "✅ tkvoice service installed successfully, use the following commands to manage:"
echo ""
echo "# Start service"
echo "./tkvoice.sh start"