doanh nghiệp FAB – EIS
Để tích hợp khả năng nhận dạng tiếng nói cho phần mềm kế toán và quản trị doanh nghiệp, tác giả đã nghiên cứu và đề xuất hai giải pháp:
- Xây dựng giao tiếp tiếng nói như một chương trình độc lập, sử dụng cơ chế Hook để can thiệp vào phần mềm nhằm đáp ứng các lệnh phù hợp với tiếng nói của người sử dụng.
- Xây dựng giao tiếp tiếng nói như một module của phần mềm kế toán và quản trị doanh nghiệp FAB – EIS
2.2.1. Xây dựng giao tiếp tiếng nói nhƣ một chƣơng trình độc lập 2.2.1.1. Giới thiệu về kỹ thuật Hook
Hook là một kỹ thuật phổ biến trong lập trình, đặc biệt là các ứng dụng cần can thiệp vào quá trình gửi/nhận thông điệp của một chương trình khác. Một ví dụ phổ biến của hook là các chương trình gõ tiếng Việt như Unikey,VietKey… Các phần mềm gián điệp, virus cũng thường sử dụng kỹ thuật này để đánh cắp thông tin khi người dùng thao tác với hệ thống.
Phụ thuộc vào từng hệ điều hành cụ thể, cơ chế Hook được sử dụng theo nhiều cách khác nhau. Dưới đây là giới thiệu cơ chế Hook trên hệ điều hành MS Windows 32 bit.
30
Trong hệ điều hành Windows, các ứng dụng đáp ứng yêu cầu người dùng thông qua việc xử lý các thông điệp nhận được từ hệ điều hành. Khi người dùng gõ một phím, hay nhập chuột…, hệ điều hành sẽ sinh ra một sự kiện tương ứng và gửi sự kiện cùng các dữ liệu cần thiết đến các cửa sổ tương ứng.
Windows cung cấp các API cần thiết để ứng dụng thứ ba có thể can thiệp vào quá trình chuyển giao thông điệp giữa hệ điều hành và ứng dụng. Dựa trên các API này, ứng dụng thứ ba có thể đọc, ghi, chỉnh sửa thông tin thông điệp theo thiết kế của mình, do đó sẽ thay đổi các đáp ứng sự kiện của ứng dụng gốc. Kỹ thuật này được áp dụng trong lập trình hệ thống, cũng như bị lợi dụng bởi các ứng dụng virus nhằm đánh cắp thông tin.
Hệ điều hành Windows quản lý các thông điệp sử dụng hàng đợi (Queue). Các sự kiện sẽ lần lượt được sử lý theo mức độ ưu tiên và thứ tự trong hàng đợi này.
Có hai cách cài đặt Hook:
- Hook cục bộ (Thread Hook): Kỹ thuật áp dụng hạn chế trong phạm vi một tiểu trình hoặc một ứng dụng cụ thể. Khi cài đặt kỹ thuật Hook này, chương trình chỉ có thể giám sát quá trình gửi/nhận thông điệp trong một chương trình hoặc một tiến trình xác định. Các Hook cục bộ được cài đặt bằng lời gọi API ngay trong chương trình.
- Hook toàn cục (Global Hook): Kỹ thuật áp dụng giám sát toàn bộ các thông điệp trong hệ thống, không bị hạn chế trong một ứng dụng cụ thể. Ứng dụng kỹ thuật này, bạn có thể giám sát quá trình gửi/nhận thông điệp tới tất cả các ứng dụng đang thực thi trên nên hệ điều hành. Các Global Hook. Các Hook toàn cục được cài đặt thành một thư viện riêng ( dạng .dll).
Các loại Hook được cung cấp trên hệ điều hành Windows:
- WH_KEYBOARD: giám sát các thông điệp từ bàn phím như phím được gõ WM_KEYDOWN, hay người dùng nhả phím sau khi gõ WM_KEYUP, … - WH_MOUSE: giám sát các thông điệp từ chuột như nhấn chuột, nhả chuột,
cuộn con lăn…
- WH_GETMESSAGE: giám sát quá trình gửi/nhận tất cả các thông điệp gồm cả thông điệp bàn phím, chuột, và các thông điệp khác…
- WH_CBT: giám sát các sự kiện tạo lập, kích hoạt, hủy, thay đổi kích thước… của cửa sổ giao diện,
- WH_JOURNALPLAYBACK: được sử dụng để sinh ra một thông điệp về chuột hoặc bàn phím tùy ý trong hàng đợi thông điệp. Đây là một loại Hook toàn cục.
- WH_JOURANLRECORD: giám sát và ghi nhận các thao tác từ chuột và bàn phím. Đây là một loại Hook toàn cục.
31 - …
Trên hệ điều hành Windows, kỹ thuật Hook được cài đặt dễ dàng sử dụng ngôn ngữ lập trình C++. Dưới đây là dạng chung của một thủ tục Hook:
LRRESULT CALLBACK HookProc( int nCode, WPARAM wParam, LPARAM lParam);
Các tham số của thủ tục Hook:
- nCode: mã loại Hook được sử dụng, tùy chọn theo mục đích cài đặt Hook, - wParam, lParam: các thông tin của thông điệp hook.
Các loại Hook khác nhau được cài đặt theo các cách khác nhau sử dụng các hàm được cung cấp sẵn của Windows API như: SetWindowsHook hay SetWindowsHookEX.
Hoàn toàn có thể xây dựng một chuỗi Hook gồm nhiều phương thức Hook nối tiếp nhau cho việc xử lý một thông điệp.
Hệ điều hành Windows lưu trữ chuỗi Hook trong một danh sách con trỏ và gọi lần lượt các Hook này khi điều kiện của Hook xuất hiện.
Các hàm thao tác với Hook:
- SetWindowsHookEx: Đăng ký thủ tục xử lý hook,
- CallNextHookEx: Gọi tới thủ tục xử lý Hook tiếp theo trong hàng đợi sự kiện,
- UnHookWindowsHookEx: Hủy đăng ký xử lý sự kiện. Ví dụ một thủ tục Hook bàn phím:
#include <Windows.h> #include <stdio.h>
//vùng nhớ dùng chung, chứa biến handle của Hook #pragma data_seg("SHARED_DATA")
HHOOK hGlobalHook = NULL; #pragma data_seg()
//hàm lọc sự kiện nhấn phím
__declspec(dllexport) LRESULT CALLBACK FillKeyboard(int nCode, WPARAM wParam, LPARAM lParam)
{
// Người dùng ấn phím Enter
32 {
MessageBox(0, "Hello World ", "Hook Example", 0); return 1;
}
//Gọi tới thủ tục Hook tiếp theo
return CallNextHookEx(hGlobalHook, nCode, wParam, lParam); }
//hàm ấn định biến hGlobalHook tại vùng nhớ dùng chung
__declspec(dllexport) void SetGlobalHookHandle(HHOOK hHook) {
hGlobalHook = hHook; }
2.2.1.2. Ứng thủ tục Hook trong xây dựng giao tiếp tiếng nói với phần mềm kế toán và quản trị doanh nghiệp
Trong giải pháp này, phần mềm nhận dạng tiếng nói được xây dựng chạy độc lập với phần mềm kế toán quản trị doanh nghiệp. Các kết quả nhận dạng sẽ được chuyển thành các lệnh tương ứng, sau đó sử dụng kỹ thuật Hook gửi thông điệp thích hợp đến phần mềm kế toán và quản trị doanh nghiệp nhằm thực hiện thao tác người dùng mong muốn.
Vì xây dựng như một sản phẩm riêng biệt, nên chương trình nhận dạng tiếng nói phải sử dụng kỹ thuật Hook toàn cục để có thể gửi các thông điệp sang một chương trình khác. Điều này cũng yêu cầu người phát triển xây dựng môt thư viện riêng (trong hệ điều hành Windows đó là các file DLL) phục vụ quá trình xử lý Hook.
33
2.2.2. Xây dựng giao tiếp tiếng nói nhƣ một module thuộc phần mềm kế toán và quản trị doanh nghiệp
Theo giải pháp này, khả năng nhận dạng tiếng nói được xây dựng thành một module riêng và được tích hợp như một thành phần của phần mềm kế toán và quản trị doanh nghiệp FAB – EIS. Điều này đồng nghĩa với việc ngôn ngữ lập trình Java được sử dụng, do đó tính độc lập nền tảng của phần mềm vẫn được bảo toàn. Phần mềm hoàn toàn có thể thực thi trên các nền tảng hỗ trợ Java mà không phụ thuộc vào một hệ điều hành cụ thể.
Do phần mềm FAB – EIS được xây dựng sử dụng ngôn ngữ lập trình Java, nên việc sử dụng công cụ SPHINX hỗ trợ rất lớn cho quá trình xây dựng khả năng nhận dạng tiếng nói của phần mềm.
Tuy nhiên, sử dụng kỹ thuật này đòi hỏi người phát triển phải có mã nguồn của phần mềm kế toán và quản trị doanh nghiệp FAB – EIS.
2.2.3. Đánh giá và lựa chọn giải pháp
Với hai giải pháp trên ta dễ dạng nhận thấy việc sử dụng kỹ thuật Hook có một số ưu điểm như: không can thiệp vào mã nguồn phần mềm kế toán và quản trị doanh nghiệp FAB – EIS, triển khai độc lập hoàn toàn với phần mềm FAB – EIS và có thể tái sử dụng cho nhiều hệ thống khác nhau. Tuy nhiên việc cài đặt thư viện Hook tương đối phức tạp và phụ thuộc vào môi trường thực thi; ví dụ khi cài đặt
Bắt đầu
Nhận dạng tiếng nói
Chuyển tiếng nói thành thông điệp
Chuyển thông điệp tới phần mềm FAB - EIS Người dùng dừng nhận dạng? Kết thúc - +
34
trên hệ điều hành Windows ta cần xây dựng một chương trình, trên hệ điều hành Linux ta cần xây dựng một chương trình khác, do cơ chế Hook và API trên các hệ điều hành khác nhau là khác nhau. Mặt khác, việc tìm kiếm, quản lý và gửi thông điệp tới một chương trình khác rất dễ xảy ra lỗi, tiềm ẩn khả năng gây lỗi phần mềm kế toán, quản trị doanh nghiệp FAB – EIS.
Giải pháp thứ hai xây dựng khả năng nhận dạng tiếng nói như một module trong phần mềm kế toán và quản trị doanh nghiệp FAB – EIS tuy phải can thiệp trực tiếp vào mã nguồn phần mềm, nhưng sự can thiệp này tương đối ít chỉ một đoạn nhỏ để kích hoạt khả năng nhận dạng và xử lý lệnh mà người dùng phát ra. Giải pháp cũng giúp hạn chế công sức lập trình rất nhiều khi ngôn ngữ lập trình Java có công cụ hỗ trợ nhận dạng tiếng nói hữu hiệu là SPHINX.
Bên cạnh đó việc lập trình sử dụng ngôn ngữ Java giúp phần mềm kế toán và quản trị doanh nghiệp FAB – EIS vẫn giữ được tính đa nền tảng khi triển khai trên các hệ điều hành khác nhau mà không cần phải biên dịch lại chương trình.
Dựa trên những lý do đó, tác giả đã lựa chọn giải pháp tích hợp trực tiếp khả năng nhận dạng tiếng nói như một module của phần mềm kế toán và quản trị doanh nghiệp FAB – EIS.
35
CHƢƠNG 3
BỘ CÔNG CỤ SPHINX 3.1. Giới thiệu
Sphinx 4 là một hệ thống nhận dạng ngôn ngữ thuần Java, là kết quả của sự hợp tác giữa Đại học Carnegie Mellon, Sun Microsystems Laboratories, Mitsubishi Electric Research Labs (MERL), and Hewlett Packard (HP), cũng như sự đóng góp của đaij học California và học viện công nghệ Massachusetts.
Sphinx 4 có khả năng linh động và tính module hóa rất cao. Sơ đồ dưới đây là kiến trúc tổng quan của Sphinx 4:
Hình 16 Sơ đồ kiến trúc Sphinx 4
Sphinx 4 có 3 thành phần chính phục vụ cho ba mục đích khác nhau:
- FrontEnd: Nhận các tín hiệu đầu vào, và tham số hóa chúng thành các đặc trưng của tiếng nói.
- Decoder: Sử dụng đặc trưng tiếng nói được cung cấp bởi FrontEnd và đồ thị tìm kiếm SearchGraph trích xuất từ dữ liệu ngôn ngữ Linguist nhằm thực hiện quá trình giải mã, và trả về kết quả Result cho ứng dụng.
- Linguist: lưu trữ, xử lý các thông tin về ngôn ngữ như từ điển âm học, mô hình ngôn ngữ, mô hình âm học. Linguist sử dụng thông tin từ những thành phần này, nhằm tổ hợp ra một đồ thị tìm kiếm SearchGraph phục vụ cho quá trình giải mã.
36
Sphinx 4 cung cấp lượng lớn các tham số cấu hình nhằm điều chính hiệu năng hệ thống ví dụ như độ sâu tìm kiếm… Đặc biệt Sphinx 4 cung cấp khả năng cấu hình động thông qua lớp ConfigurationManager giúp cho các hệ thống sử dụng sphinx trở lên linh động hơn rất nhiều.
Bên cạnh đó Sphix 4 cũng cung cấp các bộ công cụ trợ giúp người dùng trong việc phân tích hệ thống như tương tác với môi trường khi đang thực thi, thay đổi tham số lúc chạy…
3.2. FrontEnd
FrontEnd được sử dụng để tham số hóa các tín hiệu đầu vào. Hình dưới mô tả quá trình trích chọn đặc trưng từ tín hiệu đầu vào của FrontEnd:
Hình 17 FrontEnd
Việc cho phép xử lý nhiều đầu vào cho phép FrontEnd có khả năng tính toán song song nhiều loại tham số khác nhau từ một hoặc nhiều tín hiệu đầu vào. Điều này cũng tạo nên khả năng giải mã song song sử dụng các tham số khác nhau.
Mỗi DataProcessor có một đầu vào và đầu ra, đầu ra của DataProcessor này có thể là đầu vào của DataProcessor khác. Tín hiệu đầu ra và đầu vào của DataProcessor là Data. DataProcessor cuối cùng có đầu ra là một đối tượng Data đã được tham số hóa, hay còn gọi là đặc trưng (Features) của tín hiệu đầu vào. Các đặc trưng này sẽ được sử dụng cho bộ Decoder.
Sphinx 4 cho phép sinh ra các đặc trưng một các song song, và số lượng các luồng sử lý song song có thể thay đổi tùy ý.
Các DataProcessor giao tiếp với nhau dựa trên mô hình pull, chúng chỉ yêu cầu tín hiệu đầu vào từ thành phần trước chỉ khi cần thiết. Việc sử dụng mô hình pull giúp bộ xử lý có thể thực hiện các chức năng như bộ đệm, hoặc tìm kiếm quay lui…
Sphinx 4 cung cấp khả năng cấu hình các kỹ thuật xử lý tín hiệu thông dụng như: DCT, LPC,…
Các cấu hình cho FrontEnd có thể được thực hiện thông qua lớp ConfigurationManager.
37
3.3. Linguist
Module Linguist được sự dụng để sinh đồ thị tìm kiếm SearchGraph. Giống như các thành phần khác Linguist có khả năng pluggable giúp người dung có thể cấu hình động hệ thống với nhiều cài đặt linguist khác nhau.
Linguist tạo ra đồ thị tìm kiếm SearchGraph bằng cách sử dụng cấu trúc ngôn ngữ (được biểu diễn bởi mô hình ngôn ngữ LanguageModel cho trước) và kiến trúc âm học của mô hình âm học AcousticModel (mô hình Markov ẩn cho các âm). Linguist cũng sử dụng từ điển Dictionary để ánh xạ các từ trong mô hình ngôn ngữ với các phần tử tương ứng trong mô hình âm học AcousticModel.
Linguist gồm 3 thành phần pluggable: Mô hình ngôn ngữ - LanguageModel, Từ điển – Dictionary, và mô hình âm học – AcousticModel.
3.3.1. Mô hình nguôn ngữ - LanguageModel
Mô hình ngôn ngữ biểu diễn kiến trúc ngôn ngữ ở mức từ vựng, có thể được cài đặt theo nhiều cách khác nhau. Các cài đặt này thông thường chi làm hai loại: ngữ pháp hướng đồ thị và mô hình thống kê N-Gram.
Ngữ pháp hướng đồ thị biểu diễn một đồ thị có hướng trong đó mỗi nút biễu diễn một từ đơn, mỗi cạnh biểu diễn xác suất từ có thể đi sau từ đó.
Mô hình thống kê N-Gram cung cấp xác suất của từ xuất hiện trước n – 1 từ khác. Mô hình ngôn ngữ trong Sphinx 4 hỗ trợ nhiều định dạng khác nhau:
- SimpleWordListGrammar: định nghĩa ngữ pháp dựa trên danh sách các từ. - JSGFGrammar: hỗ trợ JavaTM Speech API Grammar Format(JSGF)
- LMGrammar: định nghĩa ngữ pháp dựa trên một mô hình ngôn ngữ thống kê. Mô hình này làm việc tốt với các ngôn ngữ xấp xỉ 1000 từ.
- FSTGrammar: Hỗ trợ máy hữu hạn trạng thái theo định dạng ngữ pháp ARPA FST.
- SimpleNGramModel: cung cấp mô hình ngôn ngữ ASCII N – Gram theo định dạng ARPA. Mô hình này không tối ưu hóa bộ nhớ sử dụng, do đó chỉ phù hợp với các mô hình ngôn ngữ nhỏ.
- LargeTrigramModel: được sinh ra sử dụng bộ công cụ ngôn ngữ CMU, tối ưu hóa bộ nhớ, cho phép làm việc với các file lớn từ 100MB trở lên.
3.3.2. Từ điển - Dictionary
Từ điển cung cấp phương thức phát âm cho các từ của mô hình ngôn ngữ. Cách thức phát âm sẽ chi từ thành các phần nhỏ hơn xuất hiện trong mô hình âm học. Từ điển hỗ trợ phân loại các từ và cho phép một từ đơn được xếp vào nhiều lớp khác nhau.
38 Dictionary.
3.3.3. Mô hình âm học AcousticModel
Mô hình âm học cung cấp ánh xạ giữa các thành phần tiếng nói và mô hình Markov ẩn. Việc ánh xạ này có thể bao gồm cả thông tin về ngữ cảnh và vị trí của từ.
Thông thường, Linguist chia các từ thành các tiểu từ độc lập ngữ cảnh, sau đó truy vấn đồ thị Markov ẩn cho các tiểu từ này, đồ thị được tìm thấy sẽ kết hợp với mô hình âm học AcousticModel đẻ tạo nên đồ thị tìm kiếm GraphSearch.
Không giống như các hệ nhận dạng tiếng nói khác, đồ thị HMM không được biểu diễn dưới dạng cấu trúc cố định, mà chỉ đơn thuần là một đồ thị có hướng, ở đó mỗi nút biểu diễn một trạng thái của mô hình, mỗi cạnh biểu diễn xác suất chuyển trạng thái giữa hai nút. Cách thức biểu diễn này giúp mô hình âm học có khả năng hỗ trợ mô hình Markov ẩn với nhiều kiến trúc khác nhau.