I have a Vespa instance that I deploy directly from my Application Package. My document schema includes several rank-profiles that are correctly used in query requests. However, I need to define various query settings for my application and want to set them via query-profiles in Vespa. Settings like userInput or FuzzySearch work as expected, but settings related to rank-profiles do not.
I would like to set query conditions like 'input.query(q) = embed(e5,@query)' or 'ranking = "my_rank_profile"' via query-profile.
schema doc {
document doc {
field subject type string {
indexing: summary | attribute | index
index: enable-bm25
attribute {
fast-search
}
}
field body type array<string> {
indexing: summary | attribute | index
index: enable-bm25
attribute {
fast-search
}
}
field body_embedding type tensor<bfloat16>(p{},x[1024]) {
indexing: input body | embed e5 | attribute | index
attribute {
distance-metric: angular
}
index {
hnsw {
max-links-per-node: 16
neighbors-to-explore-at-insert: 200
}
}
}
fieldset default {
fields: subject, body
}
rank-profile my_rank_profile {
inputs {
query(q) tensor<bfloat16>(x[1024])
query(subjectWeight) : 3
}
function weighted_subject() {
expression {
nativeRank(subject) * query(subjectWeight)
}
}
first-phase {
expression {
cos(distance(field,body_embedding)) + weighted_subject
}
}
match-features {
query(subjectWeight)
weighted_subject
firstPhase
}
}
}
Vespa Version: 8.448.13
<query-profile id="UserInputProfile">
<field name="yql">select * from sources * where %{user-input}</field>
<field name="user-input">({targetHits:10, weight:%{.user-input-weight}}userInput(@query))</field>
<field name="user-input-weight">20</field>
</query-profile>
Request JSON body:
{
"query": "some user query",
"queryProfile": "UserInputProfile"
}
Query-profile type:
<query-profile-type id="NearestNeighborTypes">
<field name="yql" type="string"/>
<field name="nn-input" type="string"/>
<field name="input.query(q)" type="tensor(x[1024])"/>
<field name="input.query(subjectWeight)" type="float"/>
<field name="ranking" type="string"/>
</query-profile-type>
Query-profile:
<query-profile id="NearestNeighborProfile" type="NearestNeighborTypes">
<field name="yql">select * from sources * where %{.nn-input} or userQuery()</field>
<field name="nn-input">({targetHits:10}nearestNeighbor(body_embedding,q))</field>
<field name="input.query(q)">embed(e5,@query)</field>
<field name="input.query(subjectWeight)">5</field>
<field name="ranking">my_rank_profile</field>
</query-profile>
Request JSON body:
{
"query": "some user query",
"queryProfile": "NearestNeighborProfile"
}
Uploading application package... failed
Error: invalid application package (status 400)
Invalid application:
Error reading query profile 'NearestNeighborProfile' of type 'NearestNeighborTypes':
Could not set 'input.query(q)' to 'embed(e5,@query)':
Can't find embedder 'e5'. Available embedder ids are 'default'.
In my services.xml, I have the following embedder configuration:
<component id="e5" type="hugging-face-embedder">
<transformer-model url="https://github.com/vespa-engine/sample-apps/raw/master/simple-semantic-search/model/e5-small-v2-int8.onnx"/>
<tokenizer-model url="https://raw.githubusercontent.com/vespa-engine/sample-apps/master/simple-semantic-search/model/tokenizer.json"/>
<prepend> <!-- E5 prompt instructions -->
<query>query:</query>
<document>passage:</document>
</prepend>
</component>
Since it works fine when I directly specify the 'embed(e5,@query)' in the request body, I assume the embedder is correctly registered.
Is this behavior not supported by Vespa, or am I doing something wrong?
Try replacing "ranking" with "ranking.profile" - per https://docs.vespa.ai/en/reference/query-api-reference.html this is the full name and https://docs.vespa.ai/en/query-profiles.html#using-a-query-profile you cannot use aliases ("ranking" is an alias).
I think this will at least solve the problem with the missing ranking profile data