O SDK for Go encapsula diversos formatos de entrada e saída, incluindo TensorFlow, PyTorch e strings, além de suportar a invocação assíncrona do queue service. Este tópico descreve cada API e fornece exemplos completos de código.
Para obter informações sobre os casos de uso e os princípios de invocação do SDK, consulte Service invocation SDKs.
Pré-requisitos
A ferramenta de gerenciamento de pacotes Go baixa automaticamente o código do SDK durante a compilação. Não é necessário instalar o SDK antecipadamente. Para personalizar a lógica de invocação, primeiro baixe o código do SDK for Go e depois modifique-o.
Para importar o SDK, use o seguinte código:
import (
"github.com/pai-eas/eas-golang-sdk/eas"
)
Início rápido
Selecione a classe Request correspondente ao formato dos dados de entrada do seu modelo. O exemplo abaixo demonstra uma invocação mínima e completa usando uma requisição do tipo string.
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "my_service")
client.SetToken("YOUR_SERVICE_TOKEN")
client.Init()
resp, err := client.StringPredict("[{}]")
if err != nil {
fmt.Printf("failed to predict: %v\n", err.Error())
} else {
fmt.Printf("%v\n", resp)
}
}
Referência da API
O SDK for Go oferece as seguintes classes de API, divididas em três grupos conforme sua finalidade:
Grupo | Descrição |
Cliente principal | PredictClient: Configura as informações do service (Endpoint / ServiceName / Token), envia requisições e recebe respostas. |
Entrada e saída |
|
queue service |
|
PredictClient
Classe principal do cliente usada para configurar informações do service, enviar requisições e receber resultados de previsão.
Método | Descrição |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Inicializa o objeto PredictClient. Após definir todos os parâmetros, chame |
|
|
|
|
|
|
|
|
TFRequest
Monta os dados de entrada para modelos TensorFlow.
Método | Descrição |
|
|
|
|
|
|
TFResponse
Analisa os dados de saída de modelos TensorFlow.
Método | Descrição |
|
|
|
TorchRequest
Monta os dados de entrada para modelos PyTorch.
Método | Descrição |
| Construtor da classe TorchRequest. |
|
|
|
|
TorchResponse
Analisa os dados de saída de modelos PyTorch.
Método | Descrição |
|
|
|
QueueClient
Interage com o queue service do EAS para produzir, consumir e gerenciar dados.
Método | Descrição |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
types.Watcher
Lê dados enviados do canal de assinatura do queue service.
Método | Descrição |
|
|
| Fecha um objeto watcher e sua conexão de dados de backend. Nota Um cliente pode ter apenas um objeto watcher ativo por vez. Você deve fechar o objeto watcher atual antes de criar um novo. |
Exemplos
Inferência síncrona por formato
Escolha o exemplo de código com base nos tipos de entrada e saída do seu service.
String
Ao implantar um service com um processador personalizado, a invocação geralmente ocorre usando strings, como ao chamar um service de modelo PMML. O programa abaixo mostra um exemplo completo.
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "scorecard_pmml_example")
client.SetToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****")
client.Init()
req := "[{\"fea1\": 1, \"fea2\": 2}]"
for i := 0; i < 100; i++ {
resp, err := client.StringPredict(req)
if err != nil {
fmt.Printf("failed to predict: %v\n", err.Error())
} else {
fmt.Printf("%v\n", resp)
}
}
}
TensorFlow
Para modelos TensorFlow, use TFRequest e TFResponse como formatos de dados de entrada e saída, respectivamente. O programa abaixo mostra um exemplo completo.
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "mnist_saved_model_example")
client.SetToken("YTg2ZjE0ZjM4ZmE3OTc0NzYxZDMyNmYzMTJjZTQ1YmU0N2FjMTAy****")
client.Init()
tfreq := eas.TFRequest{}
tfreq.SetSignatureName("predict_images")
tfreq.AddFeedFloat32("images", []int64{1, 784}, make([]float32, 784))
for i := 0; i < 100; i++ {
resp, err := client.TFPredict(tfreq)
if err != nil {
fmt.Printf("failed to predict: %v", err)
} else {
fmt.Printf("%v\n", resp)
}
}
}
PyTorch
Para modelos PyTorch, use TorchRequest e TorchResponse como formatos de dados de entrada e saída, respectivamente. O programa abaixo mostra um exemplo completo.
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
client := eas.NewPredictClient("182848887922****.cn-shanghai.pai-eas.aliyuncs.com", "pytorch_resnet_example")
client.SetTimeout(500)
client.SetToken("ZjdjZDg1NWVlMWI2NTU5YzJiMmY5ZmE5OTBmYzZkMjI0YjlmYWVl****")
client.Init()
req := eas.TorchRequest{}
req.AddFeedFloat32(0, []int64{1, 3, 224, 224}, make([]float32, 150528))
req.AddFetch(0)
for i := 0; i < 10; i++ {
resp, err := client.TorchPredict(req)
if err != nil {
fmt.Printf("failed to predict: %v", err)
} else {
fmt.Println(resp.GetTensorShape(0), resp.GetFloatVal(0))
}
}
}
Conexão direta VPC
Com uma conexão direta VPC, você só pode acessar services implantados em um grupo de recursos dedicado do EAS, sendo necessário conectar esse grupo de recursos ao vSwitch especificado. Para obter informações sobre como adquirir um grupo de recursos dedicado do EAS e conectar a rede, consulte Use EAS resource groups e Configure EAS to access public or internal resources. Em comparação com uma invocação padrão, este método requer apenas uma linha adicional de código, client.SetEndpointType(eas.EndpointTypeDirect), tornando-o ideal para services com alto tráfego e alta concorrência. O código a seguir mostra um exemplo:
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
)
func main() {
// Format of a VPC direct connection endpoint: {uid}.vpc.{region-id}.pai-eas.aliyuncs.com. You can find the endpoint on the Invocation Information tab of the service details page in the EAS console.
client := eas.NewPredictClient("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com", "scorecard_pmml_example")
client.SetToken("YWFlMDYyZDNmNTc3M2I3MzMwYmY0MmYwM2Y2MTYxMTY4NzBkNzdj****")
client.SetEndpointType(eas.EndpointTypeDirect)
client.Init()
req := "[{\"fea1\": 1, \"fea2\": 2}]"
for i := 0; i < 100; i++ {
resp, err := client.StringPredict(req)
if err != nil {
fmt.Printf("failed to predict: %v\n", err.Error())
} else {
fmt.Printf("%v\n", resp)
}
}
}
Parâmetros de conexão do cliente
É possível definir os parâmetros de conexão do cliente de requisição usando a propriedade http.Transport. O exemplo a seguir demonstra como configurar essas definições:
package main
import (
"fmt"
"github.com/pai-eas/eas-golang-sdk/eas"
"net/http"
"time"
)
func main() {
// Format of a VPC direct connection endpoint: {uid}.vpc.{region-id}.pai-eas.aliyuncs.com. You can find the endpoint on the Invocation Information tab of the service details page in the EAS console.
client := eas.NewPredictClient("182848887922****.vpc.cn-shanghai.pai-eas.aliyuncs.com", "network_test")
client.SetToken("MDAwZDQ3NjE3OThhOTI4ODFmMjJiYzE0MDk1NWRkOGI1MmVhMGI0****")
client.SetEndpointType(eas.EndpointTypeDirect)
client.SetHttpTransport(&http.Transport{
MaxConnsPerHost: 300,
TLSHandshakeTimeout: 100 * time.Millisecond,
ResponseHeaderTimeout: 200 * time.Millisecond,
ExpectContinueTimeout: 200 * time.Millisecond,
})
}
queue service
Use o QueueClient para enviar dados a um queue service, consultar dados, verificar o status do queue service e inscrever-se em notificações de dados vindas dele. Neste exemplo, uma goroutine envia dados para o queue service, enquanto outra usa um watcher para se inscrever e receber esses dados.
Ao implantar um service de inferência assíncrona no EAS, uma fila de entrada e uma fila de saída são geradas automaticamente. Os endereços seguem tipicamente os seguintes formatos:
Fila de entrada: <domain>/api/predict/<service_name>
Fila de saída: <domain>/api/predict/<service_name>/sink
Use <service_name> ou <service_name>/sink para construir o QueueClient conforme suas necessidades.
const (
QueueEndpoint = "182848887922****.cn-shanghai.pai-eas.aliyuncs.com"
// For example, if the EAS service name is test_qservice, the input queue name is test_qservice, and the output queue name is test_qservice/sink.
QueueName = "test_qservice"
QueueToken = "YmE3NDkyMzdiMzNmMGM3ZmE4ZmNjZDk0M2NiMDA3OTZmNzc1MTUx****"
)
queue, err := NewQueueClient(QueueEndpoint, QueueName, QueueToken)
// truncate all messages in the queue
attrs, err := queue.Attributes()
if index, ok := attrs["stream.lastEntry"]; ok {
idx, _ := strconv.ParseUint(index, 10, 64)
queue.Truncate(context.Background(), idx+1)
}
ctx, cancel := context.WithCancel(context.Background())
// create a goroutine to send messages to the queue
go func() {
i := 0
for {
select {
case <-time.NewTicker(time.Microsecond * 1).C:
_, _, err := queue.Put(context.Background(), []byte(strconv.Itoa(i)), types.Tags{})
if err != nil {
fmt.Printf("Error occured, retry to handle it: %v\n", err)
}
i += 1
case <-ctx.Done():
break
}
}
}()
// create a watcher to watch the messages from the queue
watcher, err := queue.Watch(context.Background(), 0, 5, false, false)
if err != nil {
fmt.Printf("Failed to create a watcher to watch the queue: %v\n", err)
return
}
// read messages from the queue and commit manually
for i := 0; i < 100; i++ {
df := <-watcher.FrameChan()
err := queue.Commit(context.Background(), df.Index.Uint64())
if err != nil {
fmt.Printf("Failed to commit index: %v(%v)\n", df.Index, err)
}
}
// everything is done, close the watcher
watcher.Close()
cancel()
Solução de problemas
Para sintomas, causas e diretrizes de solução de problemas relacionados a exceções de invocação do SDK for Go, incluindo questões comuns de autenticação, roteamento, conexões e servidor, consulte a seção "Solucionar exceções de invocação" em Service invocation SDKs.
Para obter uma lista completa de códigos de status do service, mensagens de erro e ações recomendadas, consulte Appendix: Service status codes and common errors.